Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
54c80ca
Add reproducer tests
alex-spies Mar 13, 2026
80773ae
[CI] Auto commit changes from spotless
Mar 13, 2026
4d37592
WIP: check what cursor did there
alex-spies Mar 13, 2026
5317911
Merge remote-tracking branch 'upstream/main' into fix-non-loaded-part…
alex-spies Mar 24, 2026
db02298
Update test
alex-spies Mar 24, 2026
c5c502f
Spotless
alex-spies Mar 24, 2026
464c088
WIP
alex-spies Mar 25, 2026
c989926
WIP: more tests
alex-spies Mar 25, 2026
65c765a
Add ability to unmap fields in CsvTestsDataLoader
alex-spies Mar 25, 2026
8d058ca
Add employees_no_names index
alex-spies Mar 25, 2026
9a2e72c
Fix, add tests
alex-spies Mar 25, 2026
a123267
Fix capabilities
alex-spies Mar 25, 2026
773fad4
Don't mess with partially mapped non-KEYWORD fields at all
alex-spies Mar 25, 2026
fc29451
Add tests
alex-spies Mar 25, 2026
631d8bc
Refactor a little
alex-spies Mar 25, 2026
318e2a9
Merge branch 'main' into fix-non-loaded-partially-mapped-fields
alex-spies Mar 25, 2026
821f3c4
Fix some tests
alex-spies Mar 26, 2026
b9ce17d
Fix CsvTests
alex-spies Mar 26, 2026
e96a952
Update capabilities
alex-spies Mar 26, 2026
fafe292
Spotless
alex-spies Mar 26, 2026
59cd9fa
Improve comment
alex-spies Mar 26, 2026
5f07932
Improve another comment
alex-spies Mar 26, 2026
81f0205
More capability fixes
alex-spies Mar 26, 2026
3484535
Remove redundant type override
alex-spies Mar 26, 2026
cecb383
Merge remote-tracking branch 'upstream/main' into fix-non-loaded-part…
alex-spies Mar 26, 2026
3a6d552
Improve comment
alex-spies Mar 26, 2026
d67b210
Simplify loadPartiallyMappedKeywordFields
alex-spies Mar 26, 2026
4daa8cd
More Andrei tests :)
alex-spies Mar 26, 2026
7f81ee4
Small cleanup
alex-spies Mar 31, 2026
0865f5d
Merge remote-tracking branch 'origin/main' into fix-non-loaded-partia…
mouhc1ne Mar 31, 2026
b7fe2ae
Merge remote-tracking branch 'origin/main' into fix-non-loaded-partia…
mouhc1ne Mar 31, 2026
0fe03fd
[CI] Auto commit changes from spotless
Mar 31, 2026
0caffa7
Fix compile errors due to EsIndex signature change, missed during con…
mouhc1ne Mar 31, 2026
f05ad5f
Merge remote-tracking branch 'fork-alex/fix-non-loaded-partially-mapp…
mouhc1ne Mar 31, 2026
4df3a71
Merge branch 'main' into fix-non-loaded-partially-mapped-fields
mouhc1ne Mar 31, 2026
edb3953
Remove duplicate no_mapping_sample_data
alex-spies Apr 1, 2026
15f7260
Merge remote-tracking branch 'upstream/main' into fix-non-loaded-part…
alex-spies Apr 2, 2026
24d608d
Fix capability
alex-spies Apr 2, 2026
eee9331
Update tests
alex-spies Apr 2, 2026
fa1c185
Move detection of PUNKs/PUKs to ResolveTable
alex-spies Apr 2, 2026
d3c8392
Make PUNKs unsupported for now
alex-spies Apr 2, 2026
88090a3
Remove redundant tests
alex-spies Apr 2, 2026
0f1a378
Merge remote-tracking branch 'upstream/main' into fix-non-loaded-part…
alex-spies Apr 2, 2026
7bf841f
Update golden tests
alex-spies Apr 2, 2026
b328373
[CI] Auto commit changes from spotless
Apr 2, 2026
4e7aa3b
Merge remote-tracking branch 'upstream/main' into fix-non-loaded-part…
alex-spies Apr 7, 2026
8b985b9
Load only the mapped data for PUNKs
alex-spies Apr 7, 2026
cc4ba1b
Put verification back in to avoid using PUNKs
alex-spies Apr 7, 2026
43f3b9e
Fix golden tests
alex-spies Apr 7, 2026
c04ae5a
Small cleanup
alex-spies Apr 7, 2026
661515d
Add capability
alex-spies Apr 8, 2026
1981333
Fix error message
alex-spies Apr 8, 2026
fd3b6d0
Remove obsolete test
alex-spies Apr 8, 2026
7124116
Fix test expectation
alex-spies Apr 8, 2026
467d36b
Fix yaml tests
alex-spies Apr 8, 2026
846be26
[CI] Auto commit changes from spotless
Apr 8, 2026
2bdb108
Fix capabilities in spec tests
alex-spies Apr 9, 2026
b9d00c3
Move new spec tests to unmapped-type-conflicts
alex-spies Apr 9, 2026
8178c7f
Align test names
alex-spies Apr 9, 2026
cde5435
Add reproducer for #145206
alex-spies Apr 9, 2026
1945de3
Merge remote-tracking branch 'upstream/main' into fix-non-loaded-part…
alex-spies Apr 9, 2026
c2d0abb
Merge branch 'main' into fix-non-loaded-partially-mapped-fields
alex-spies Apr 9, 2026
30c05da
Merge remote-tracking branch 'upstream/main' into fix-non-loaded-part…
alex-spies Apr 10, 2026
12fc233
Add tests with union types
alex-spies Apr 10, 2026
d7e680e
Add date/nanos tests
alex-spies Apr 10, 2026
b4ac2d3
Add tests without KEEP/DROP
alex-spies Apr 10, 2026
c3b4460
Fix capability
alex-spies Apr 10, 2026
b39181b
Add more golden tests
alex-spies Apr 10, 2026
89f31af
More tests with KEEP + wildcard
alex-spies Apr 10, 2026
26dadac
Another TS test
alex-spies Apr 10, 2026
d41f435
Tests with subfields
alex-spies Apr 10, 2026
69b8b2b
[CI] Auto commit changes from spotless
Apr 10, 2026
e05eccd
Add test: conflict + PUNK in same EVAL
alex-spies Apr 10, 2026
6288b50
Merge remote-tracking branch 'upstream/main' into fix-non-loaded-part…
alex-spies Apr 10, 2026
4efaf41
Update docs/changelog/144228.yaml
alex-spies Apr 13, 2026
f06775a
Merge branch 'main' into fix-non-loaded-partially-mapped-fields
alex-spies Apr 13, 2026
5262284
Improve comments
alex-spies Apr 13, 2026
3ad660f
Merge branch 'main' into fix-non-loaded-partially-mapped-fields
mouhc1ne Apr 13, 2026
b12ba12
Merge remote-tracking branch 'upstream/main' into fix-non-loaded-part…
alex-spies Apr 14, 2026
9a0e6b5
Fix some capability requirements
alex-spies Apr 14, 2026
e46e942
Fix some more tests
alex-spies Apr 14, 2026
88e23ad
Fix last tests
alex-spies Apr 14, 2026
143a74c
Fix one more spec test
alex-spies Apr 14, 2026
d8de54e
Merge remote-tracking branch 'upstream/main' into fix-non-loaded-part…
alex-spies Apr 14, 2026
724c562
Whack one more test
alex-spies Apr 14, 2026
86967b7
Merge remote-tracking branch 'upstream/main' into fix-non-loaded-part…
alex-spies Apr 14, 2026
d6791ae
And one more
alex-spies Apr 14, 2026
08321ae
Last one, hopefully
alex-spies Apr 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.APPROXIMATION_V5;
import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.FORK_V9;
import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.METRICS_GROUP_BY_ALL;
import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.OPTIONAL_FIELDS_V2;
import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.OPTIONAL_FIELDS_V4;
import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.SUBQUERY_IN_FROM_COMMAND;
import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.UNMAPPED_FIELDS;
import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.VIEWS_WITH_BRANCHING;
Expand Down Expand Up @@ -66,7 +66,7 @@ protected void shouldSkipTest(String testName) throws IOException {
// FORK is not supported with unmapped_fields="load", see https://github.com/elastic/elasticsearch/issues/142033
assumeFalse(
"FORK is not supported with unmapped_fields=\"load\"",
testCase.requiredCapabilities.contains(OPTIONAL_FIELDS_V2.capabilityName())
testCase.requiredCapabilities.contains(OPTIONAL_FIELDS_V4.capabilityName())
);

assumeFalse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,8 @@ public void close() {
for (int i = 0; i < entries.length; i++) {
String[] header = entries[i].split(":");
String name = header[0].trim();
String typeName = (typeMapping != null && typeMapping.containsKey(name)) ? typeMapping.get(name)
String typeName = (typeMapping != null && typeMapping.containsKey(name) && typeMapping.get(name) != null)
? typeMapping.get(name)
: header.length > 1 ? header[1].trim()
: null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
Expand Down Expand Up @@ -88,6 +89,17 @@ public class CsvTestsDataLoader {
new TestDataset("employees", "mapping-default.json", "employees.csv").noSubfields(),
new TestDataset("voyager", "mapping-voyager.json", "voyager.csv").noSubfields(),
new TestDataset("employees_incompatible", "mapping-default-incompatible.json", "employees_incompatible.csv").noSubfields(),
new TestDataset("employees", "mapping-default.json", "employees.csv").withIndex("employees_no_names")
.withTypeMapping(removeFields("first_name", "last_name"))
.withDynamic("false")
.noSubfields(),
new TestDataset("employees", "mapping-default.json", "employees.csv").withIndex("employees_gender_text")
.withTypeMapping(Map.of("gender", "text"))
.noSubfields(),
new TestDataset("employees", "mapping-default.json", "employees.csv").withIndex("employees_no_gender")
.withTypeMapping(removeFields("gender"))
.withDynamic("false")
.noSubfields(),
new TestDataset("all_types", "mapping-all-types.json", "all-types.csv"),
new TestDataset("hosts"),
new TestDataset("apps"),
Expand All @@ -108,6 +120,8 @@ public class CsvTestsDataLoader {
new TestDataset("ul_logs"),
new TestDataset("sample_data"),
new TestDataset("partial_mapping_sample_data"),
// TODO: withTypeMapping should be redundant here, mapping-no_mapping_sample_data.json doesn't provide any mapping where types could
// be overridden
new TestDataset("no_mapping_sample_data", "mapping-no_mapping_sample_data.json", "partial_mapping_sample_data.csv").withTypeMapping(
Comment thread
alex-spies marked this conversation as resolved.
Outdated
Stream.of("timestamp", "client_ip", "event_duration").collect(toMap(k -> k, k -> "keyword"))
),
Expand Down Expand Up @@ -767,25 +781,52 @@ private static void load(RestClient client, TestDataset dataset, IndexCreator in
}
}

/**
* Creates a type mapping that removes the given fields from the mapping.
* For use with {@link TestDataset#withTypeMapping}.
*/
private static Map<String, String> removeFields(String... fields) {
var map = new HashMap<String, String>();
for (String field : fields) {
map.put(field, null);
}
return map;
}

public static String readMappingFile(TestDataset dataset) throws IOException {
String mappingJsonText = dataset.loadMappings();
if (dataset.typeMapping == null || dataset.typeMapping.isEmpty()) {
boolean hasTypeMappingOverrides = dataset.typeMapping != null && dataset.typeMapping.isEmpty() == false;
if (hasTypeMappingOverrides == false && dataset.dynamic == null) {
return mappingJsonText;
}
boolean modified = false;
ObjectMapper mapper = new ObjectMapper();
JsonNode mappingNode = mapper.readTree(mappingJsonText);
JsonNode propertiesNode = mappingNode.path("properties");

for (Map.Entry<String, String> entry : dataset.typeMapping.entrySet()) {
String key = entry.getKey();
String newType = entry.getValue();

if (propertiesNode.has(key)) {
modified = true;
((ObjectNode) propertiesNode.get(key)).put("type", newType);
if (hasTypeMappingOverrides) {
ObjectNode propertiesNode = (ObjectNode) mappingNode.path("properties");
for (Map.Entry<String, String> entry : dataset.typeMapping.entrySet()) {
String key = entry.getKey();
String newType = entry.getValue();

if (newType == null) {
// null value means remove the field from the mapping
if (propertiesNode.has(key)) {
propertiesNode.remove(key);
modified = true;
}
} else if (propertiesNode.has(key)) {
((ObjectNode) propertiesNode.get(key)).put("type", newType);
modified = true;
}
}
}

if (dataset.dynamic != null) {
((ObjectNode) mappingNode).put("dynamic", dataset.dynamic);
modified = true;
}

if (modified) {
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mappingNode);
}
Expand Down Expand Up @@ -1070,22 +1111,23 @@ public record TestDataset(
String dataFileName,
String settingFileName,
boolean allowSubFields,
@Nullable Map<String, String> typeMapping, // Override mappings read from mappings file
@Nullable Map<String, String> dynamicTypeMapping, // Define mappings not in the mapping files, but available from field-caps
@Nullable Map<String, String> typeMapping,
@Nullable Map<String, String> dynamicTypeMapping,
@Nullable String dynamic,
List<String> inferenceEndpoints,
List<EsqlCapabilities.Cap> requiredCapabilities
) {

public TestDataset(String indexName) {
this(indexName, "mapping-" + indexName + ".json", indexName + ".csv", null, true, null, null, List.of(), List.of());
this(indexName, "mapping-" + indexName + ".json", indexName + ".csv", null, true, null, null, null, List.of(), List.of());
}

public TestDataset(String indexName, String mappingFileName, String dataFileName) {
this(indexName, mappingFileName, dataFileName, null, true, null, null, List.of(), List.of());
this(indexName, mappingFileName, dataFileName, null, true, null, null, null, List.of(), List.of());
}

public TestDataset(String indexName, String mappingFileName, String dataFileName, String settingFileName) {
this(indexName, mappingFileName, dataFileName, settingFileName, true, null, null, List.of(), List.of());
this(indexName, mappingFileName, dataFileName, settingFileName, true, null, null, null, List.of(), List.of());
}

public TestDataset withIndex(String indexName) {
Expand All @@ -1097,6 +1139,7 @@ public TestDataset withIndex(String indexName) {
allowSubFields,
typeMapping,
dynamicTypeMapping,
dynamic,
inferenceEndpoints,
requiredCapabilities
);
Expand All @@ -1111,6 +1154,7 @@ public TestDataset withData(String dataFileName) {
allowSubFields,
typeMapping,
dynamicTypeMapping,
dynamic,
inferenceEndpoints,
requiredCapabilities
);
Expand All @@ -1125,6 +1169,7 @@ public TestDataset noData() {
allowSubFields,
typeMapping,
dynamicTypeMapping,
dynamic,
inferenceEndpoints,
requiredCapabilities
);
Expand All @@ -1139,6 +1184,7 @@ public TestDataset withSetting(String settingFileName) {
allowSubFields,
typeMapping,
dynamicTypeMapping,
dynamic,
inferenceEndpoints,
requiredCapabilities
);
Expand All @@ -1153,11 +1199,20 @@ public TestDataset noSubfields() {
false,
typeMapping,
dynamicTypeMapping,
dynamic,
inferenceEndpoints,
requiredCapabilities
);
}

/**
* Overrides the types of fields in the mapping file. Each entry maps a field name to its new type
* (e.g. {@code Map.of("client_ip", "keyword")} changes client_ip from ip to keyword).
* A {@code null} value removes the field from the mapping entirely, making it unmapped for this index.
* <p>
* This affects both the Elasticsearch index mapping (via {@link CsvTestsDataLoader#readMappingFile}) and
* the in-memory mapping used by CSV unit tests.
*/
public TestDataset withTypeMapping(Map<String, String> typeMapping) {
return new TestDataset(
indexName,
Expand All @@ -1167,11 +1222,18 @@ public TestDataset withTypeMapping(Map<String, String> typeMapping) {
allowSubFields,
typeMapping,
dynamicTypeMapping,
dynamic,
inferenceEndpoints,
requiredCapabilities
);
}

/**
* Adds field mappings that are not present in the mapping file, simulating fields discovered via field-caps
* at runtime (e.g. runtime fields). These fields are only added to the in-memory mapping used by CSV unit
* tests and are not included in the Elasticsearch index mapping. Fields already present in the mapping file
* are not overridden.
*/
public TestDataset withDynamicTypeMapping(Map<String, String> dynamicTypeMapping) {
return new TestDataset(
indexName,
Expand All @@ -1181,6 +1243,26 @@ public TestDataset withDynamicTypeMapping(Map<String, String> dynamicTypeMapping
allowSubFields,
typeMapping,
dynamicTypeMapping,
dynamic,
inferenceEndpoints,
requiredCapabilities
);
}

/**
* Sets the "dynamic" mapping parameter (e.g. "false", "strict", "runtime").
* This prevents unmapped fields in the data from being automatically indexed.
*/
public TestDataset withDynamic(String dynamic) {
return new TestDataset(
indexName,
mappingFileName,
dataFileName,
settingFileName,
allowSubFields,
typeMapping,
dynamicTypeMapping,
dynamic,
inferenceEndpoints,
requiredCapabilities
);
Expand All @@ -1195,6 +1277,7 @@ public TestDataset withInferenceEndpoints(String... inferenceEndpoints) {
allowSubFields,
typeMapping,
dynamicTypeMapping,
dynamic,
List.of(inferenceEndpoints),
requiredCapabilities
);
Expand All @@ -1209,6 +1292,7 @@ public TestDataset withRequiredCapabilities(EsqlCapabilities.Cap... requiredCapa
allowSubFields,
typeMapping,
dynamicTypeMapping,
dynamic,
inferenceEndpoints,
List.of(requiredCapabilities)
);
Expand Down
Loading
Loading