Skip to content

Commit a2ca361

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 459c101 commit a2ca361

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
@@ -132,6 +132,48 @@ public void testMetaFieldsAreIgnored() throws Exception {
132132
assertEquals(DataType.KEYWORD, esIndex.mapping().get("text").getDataType());
133133
}
134134

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

0 commit comments

Comments
 (0)