Skip to content

Commit c3150f2

Browse files
authored
Merge branch '9.0' into backport/9.0/pr-122247
2 parents 08d41a7 + 7a3df49 commit c3150f2

File tree

57 files changed

+4015
-2374
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+4015
-2374
lines changed

docs/changelog/119886.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 119886
2+
summary: Initial support for unmapped fields
3+
area: ES|QL
4+
type: feature
5+
issues: []

server/src/main/java/org/elasticsearch/index/mapper/BlockSourceReader.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.io.IOException;
2323
import java.util.ArrayList;
2424
import java.util.List;
25+
import java.util.Objects;
2526

2627
/**
2728
* Loads values from {@code _source}. This whole process is very slow and cast-tastic,
@@ -230,7 +231,7 @@ private static class BytesRefs extends BlockSourceReader {
230231

231232
@Override
232233
protected void append(BlockLoader.Builder builder, Object v) {
233-
((BlockLoader.BytesRefBuilder) builder).appendBytesRef(toBytesRef(scratch, (String) v));
234+
((BlockLoader.BytesRefBuilder) builder).appendBytesRef(toBytesRef(scratch, Objects.toString(v)));
234235
}
235236

236237
@Override

x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/expression/MetadataAttribute.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public class MetadataAttribute extends TypedAttribute {
3232
public static final String TIMESTAMP_FIELD = "@timestamp";
3333
public static final String TSID_FIELD = "_tsid";
3434
public static final String SCORE = "_score";
35+
public static final String INDEX = "_index";
3536

3637
static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(
3738
Attribute.class,
@@ -42,7 +43,7 @@ public class MetadataAttribute extends TypedAttribute {
4243
private static final Map<String, Tuple<DataType, Boolean>> ATTRIBUTES_MAP = Map.of(
4344
"_version",
4445
tuple(DataType.LONG, false), // _version field is not searchable
45-
"_index",
46+
INDEX,
4647
tuple(DataType.KEYWORD, true),
4748
IdFieldMapper.NAME,
4849
tuple(DataType.KEYWORD, false), // actually searchable, but fielddata access on the _id field is disallowed by default

x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/EsField.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,12 @@
2727
public class EsField implements Writeable {
2828

2929
private static Map<String, Writeable.Reader<? extends EsField>> readers = Map.ofEntries(
30-
Map.entry("EsField", EsField::new),
3130
Map.entry("DateEsField", DateEsField::new),
31+
Map.entry("EsField", EsField::new),
3232
Map.entry("InvalidMappedField", InvalidMappedField::new),
3333
Map.entry("KeywordEsField", KeywordEsField::new),
3434
Map.entry("MultiTypeEsField", MultiTypeEsField::new),
35+
Map.entry("PotentiallyUnmappedKeywordEsField", PotentiallyUnmappedKeywordEsField::new),
3536
Map.entry("TextEsField", TextEsField::new),
3637
Map.entry("UnsupportedEsField", UnsupportedEsField::new)
3738
);

x-pack/plugin/esql-core/src/main/java/org/elasticsearch/xpack/esql/core/type/InvalidMappedField.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public InvalidMappedField(String name, String errorMessage) {
4545
* Constructor supporting union types, used in ES|QL.
4646
*/
4747
public InvalidMappedField(String name, Map<String, Set<String>> typesToIndices) {
48-
this(name, makeErrorMessage(typesToIndices), new TreeMap<>(), typesToIndices);
48+
this(name, makeErrorMessage(typesToIndices, false), new TreeMap<>(), typesToIndices);
4949
}
5050

5151
private InvalidMappedField(String name, String errorMessage, Map<String, EsField> properties, Map<String, Set<String>> typesToIndices) {
@@ -107,12 +107,21 @@ public Map<String, Set<String>> getTypesToIndices() {
107107
return typesToIndices;
108108
}
109109

110-
private static String makeErrorMessage(Map<String, Set<String>> typesToIndices) {
110+
public static String makeErrorsMessageIncludingInsistKeyword(Map<String, Set<String>> typesToIndices) {
111+
return makeErrorMessage(typesToIndices, true);
112+
}
113+
114+
private static String makeErrorMessage(Map<String, Set<String>> typesToIndices, boolean includeInsistKeyword) {
111115
StringBuilder errorMessage = new StringBuilder();
116+
var isInsistKeywordOnlyKeyword = includeInsistKeyword && typesToIndices.containsKey(DataType.KEYWORD.typeName()) == false;
112117
errorMessage.append("mapped as [");
113-
errorMessage.append(typesToIndices.size());
118+
errorMessage.append(typesToIndices.size() + (isInsistKeywordOnlyKeyword ? 1 : 0));
114119
errorMessage.append("] incompatible types: ");
115120
boolean first = true;
121+
if (isInsistKeywordOnlyKeyword) {
122+
first = false;
123+
errorMessage.append("[keyword] enforced by INSIST command");
124+
}
116125
for (Map.Entry<String, Set<String>> e : typesToIndices.entrySet()) {
117126
if (first) {
118127
first = false;
@@ -121,7 +130,12 @@ private static String makeErrorMessage(Map<String, Set<String>> typesToIndices)
121130
}
122131
errorMessage.append("[");
123132
errorMessage.append(e.getKey());
124-
errorMessage.append("] in ");
133+
errorMessage.append("] ");
134+
if (e.getKey().equals(DataType.KEYWORD.typeName()) && includeInsistKeyword) {
135+
errorMessage.append("enforced by INSIST command and in ");
136+
} else {
137+
errorMessage.append("in ");
138+
}
125139
if (e.getValue().size() <= 3) {
126140
errorMessage.append(e.getValue());
127141
} else {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
package org.elasticsearch.xpack.esql.core.type;
8+
9+
import org.elasticsearch.common.io.stream.StreamInput;
10+
11+
import java.io.IOException;
12+
13+
/**
14+
* This class is used as a marker for fields that may be unmapped, where an unmapped field is a field which exists in the _source but is not
15+
* mapped in the index. Note that this field may be mapped for some indices, but is unmapped in at least one of them.
16+
* For indices where the field is unmapped, we will try to load them directly from _source.
17+
*/
18+
public class PotentiallyUnmappedKeywordEsField extends KeywordEsField {
19+
public PotentiallyUnmappedKeywordEsField(String name) {
20+
super(name);
21+
}
22+
23+
public PotentiallyUnmappedKeywordEsField(StreamInput in) throws IOException {
24+
super(in);
25+
}
26+
27+
public String getWriteableName() {
28+
return "PotentiallyUnmappedKeywordEsField";
29+
}
30+
}

x-pack/plugin/esql/qa/server/mixed-cluster/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/mixed/MixedClusterEsqlSpecIT.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,11 @@ protected boolean supportsIndexModeLookup() throws IOException {
8585
return hasCapabilities(List.of(JOIN_LOOKUP_V12.capabilityName()));
8686
}
8787

88+
@Override
89+
protected boolean supportsSourceFieldMapping() {
90+
return false;
91+
}
92+
8893
@Override
8994
protected boolean deduplicateExactWarnings() {
9095
/*

x-pack/plugin/esql/qa/server/multi-clusters/src/javaRestTest/java/org/elasticsearch/xpack/esql/ccq/MultiClusterSpecIT.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.JOIN_LOOKUP_V12;
5353
import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.JOIN_PLANNING_V1;
5454
import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.METADATA_FIELDS_REMOTE_TEST;
55+
import static org.elasticsearch.xpack.esql.action.EsqlCapabilities.Cap.UNMAPPED_FIELDS;
5556
import static org.elasticsearch.xpack.esql.qa.rest.EsqlSpecTestCase.Mode.SYNC;
5657
import static org.mockito.ArgumentMatchers.any;
5758
import static org.mockito.Mockito.doAnswer;
@@ -127,6 +128,8 @@ protected void shouldSkipTest(String testName) throws IOException {
127128
assumeFalse("INLINESTATS not yet supported in CCS", testCase.requiredCapabilities.contains(JOIN_PLANNING_V1.capabilityName()));
128129
assumeFalse("INLINESTATS not yet supported in CCS", testCase.requiredCapabilities.contains(INLINESTATS_V3.capabilityName()));
129130
assumeFalse("LOOKUP JOIN not yet supported in CCS", testCase.requiredCapabilities.contains(JOIN_LOOKUP_V12.capabilityName()));
131+
// Unmapped fields require a coorect capability response from every cluster, which isn't currently implemented.
132+
assumeFalse("UNMAPPED FIELDS not yet supported in CCS", testCase.requiredCapabilities.contains(UNMAPPED_FIELDS.capabilityName()));
130133
}
131134

132135
private TestFeatureService remoteFeaturesService() throws IOException {
@@ -289,4 +292,9 @@ protected boolean supportsIndexModeLookup() throws IOException {
289292
// return hasCapabilities(List.of(JOIN_LOOKUP_V10.capabilityName()));
290293
return false;
291294
}
295+
296+
@Override
297+
protected boolean supportsSourceFieldMapping() {
298+
return false;
299+
}
292300
}

x-pack/plugin/esql/qa/server/multi-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/multi_node/EsqlSpecIT.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,9 @@ public EsqlSpecIT(
3737
protected boolean enableRoundingDoubleValuesOnAsserting() {
3838
return true;
3939
}
40+
41+
@Override
42+
protected boolean supportsSourceFieldMapping() {
43+
return false;
44+
}
4045
}

x-pack/plugin/esql/qa/server/single-node/src/javaRestTest/java/org/elasticsearch/xpack/esql/qa/single_node/EsqlSpecIT.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,5 @@ protected boolean enableRoundingDoubleValuesOnAsserting() {
4242
// This suite runs with more than one node and three shards in serverless
4343
return cluster.getNumNodes() > 1;
4444
}
45+
4546
}

0 commit comments

Comments
 (0)