Skip to content

Commit 003b148

Browse files
committed
SQL: Fix merging of incompatible multi-fields (#39560)
Fix bug in IndexResolver that caused conflicts in multi-field types to be ignored up (causing the query to fail later on due to mapping conflicts). The issue was caused by the multi-field which forced the parent creation before checking its validity across mappings Fix #39547 (cherry picked from commit 4e4fe28)
1 parent 414546c commit 003b148

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/analysis/index/IndexResolver.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,9 @@ static IndexResolution mergedMapping(String indexPattern, Map<String, Map<String
324324
// if the name wasn't added before
325325
final InvalidMappedField invalidF = invalidField;
326326
final FieldCapabilities fieldCapab = fieldCap;
327-
if (!flattedMapping.containsKey(name)) {
327+
328+
EsField esField = flattedMapping.get(name);
329+
if (esField == null || (invalidF != null && (esField instanceof InvalidMappedField) == false)) {
328330
createField(name, fieldCaps, hierarchicalMapping, flattedMapping, s -> {
329331
return invalidF != null ? invalidF : createField(s, fieldCapab.getType(), emptyMap(), fieldCapab.isAggregatable());
330332
});

x-pack/plugin/sql/src/test/java/org/elasticsearch/xpack/sql/analysis/index/IndexResolverTests.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,48 @@ public void testMetaFieldsAreIgnored() throws Exception {
133133
assertEquals(DataType.KEYWORD, esIndex.mapping().get("text").getDataType());
134134
}
135135

136+
public void testMergeIncompatibleCapabilitiesOfObjectFields() throws Exception {
137+
Map<String, Map<String, FieldCapabilities>> fieldCaps = new HashMap<>();
138+
139+
int depth = randomInt(5);
140+
141+
List<String> level = new ArrayList<>();
142+
String fieldName = randomAlphaOfLength(3);
143+
level.add(fieldName);
144+
for (int i = 0; i <= depth; i++) {
145+
String l = randomAlphaOfLength(3);
146+
level.add(l);
147+
fieldName += "." + l;
148+
}
149+
150+
// define a sub-field
151+
addFieldCaps(fieldCaps, fieldName + ".keyword", "keyword", true, true);
152+
153+
Map<String, FieldCapabilities> multi = new HashMap<>();
154+
multi.put("long", new FieldCapabilities(fieldName, "long", true, true, new String[] { "one-index" }, null, null));
155+
multi.put("text", new FieldCapabilities(fieldName, "text", true, false, new String[] { "another-index" }, null, null));
156+
fieldCaps.put(fieldName, multi);
157+
158+
159+
String wildcard = "*";
160+
IndexResolution resolution = IndexResolver.mergedMapping(wildcard, fieldCaps);
161+
162+
assertTrue(resolution.isValid());
163+
164+
EsIndex esIndex = resolution.get();
165+
assertEquals(wildcard, esIndex.name());
166+
EsField esField = null;
167+
Map<String, EsField> props = esIndex.mapping();
168+
for (String lvl : level) {
169+
esField = props.get(lvl);
170+
props = esField.getProperties();
171+
}
172+
assertEquals(InvalidMappedField.class, esField.getClass());
173+
assertEquals("mapped as [2] incompatible types: [text] in [another-index], [long] in [one-index]",
174+
((InvalidMappedField) esField).errorMessage());
175+
}
176+
177+
136178
public static IndexResolution merge(EsIndex... indices) {
137179
return IndexResolver.mergedMapping("*", fromMappings(indices));
138180
}

0 commit comments

Comments
 (0)