diff --git a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/analysis/index/IndexResolver.java b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/analysis/index/IndexResolver.java index 43d356720f8..ec2dfa46f47 100644 --- a/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/analysis/index/IndexResolver.java +++ b/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/analysis/index/IndexResolver.java @@ -324,7 +324,9 @@ public class IndexResolver { // if the name wasn't added before final InvalidMappedField invalidF = invalidField; final FieldCapabilities fieldCapab = fieldCap; - if (!flattedMapping.containsKey(name)) { + + EsField esField = flattedMapping.get(name); + if (esField == null || (invalidF != null && (esField instanceof InvalidMappedField) == false)) { createField(name, fieldCaps, hierarchicalMapping, flattedMapping, s -> { return invalidF != null ? invalidF : createField(s, fieldCapab.getType(), emptyMap(), fieldCapab.isAggregatable()); }); diff --git a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/index/IndexResolverTests.java b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/index/IndexResolverTests.java index 6123bdf5d8f..0f4f8f03050 100644 --- a/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/index/IndexResolverTests.java +++ b/x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/index/IndexResolverTests.java @@ -133,6 +133,48 @@ public class IndexResolverTests extends ESTestCase { assertEquals(DataType.KEYWORD, esIndex.mapping().get("text").getDataType()); } + public void testMergeIncompatibleCapabilitiesOfObjectFields() throws Exception { + Map> fieldCaps = new HashMap<>(); + + int depth = randomInt(5); + + List level = new ArrayList<>(); + String fieldName = randomAlphaOfLength(3); + level.add(fieldName); + for (int i = 0; i <= depth; i++) { + String l = randomAlphaOfLength(3); + level.add(l); + fieldName += "." + l; + } + + // define a sub-field + addFieldCaps(fieldCaps, fieldName + ".keyword", "keyword", true, true); + + Map multi = new HashMap<>(); + multi.put("long", new FieldCapabilities(fieldName, "long", true, true, new String[] { "one-index" }, null, null)); + multi.put("text", new FieldCapabilities(fieldName, "text", true, false, new String[] { "another-index" }, null, null)); + fieldCaps.put(fieldName, multi); + + + String wildcard = "*"; + IndexResolution resolution = IndexResolver.mergedMapping(wildcard, fieldCaps); + + assertTrue(resolution.isValid()); + + EsIndex esIndex = resolution.get(); + assertEquals(wildcard, esIndex.name()); + EsField esField = null; + Map props = esIndex.mapping(); + for (String lvl : level) { + esField = props.get(lvl); + props = esField.getProperties(); + } + assertEquals(InvalidMappedField.class, esField.getClass()); + assertEquals("mapped as [2] incompatible types: [text] in [another-index], [long] in [one-index]", + ((InvalidMappedField) esField).errorMessage()); + } + + public static IndexResolution merge(EsIndex... indices) { return IndexResolver.mergedMapping("*", fromMappings(indices)); }