Skip to content

Commit 87c3fc5

Browse files
authored
Merge branch 'main' into mtv32
2 parents fa296fa + 47a3e5c commit 87c3fc5

File tree

22 files changed

+2180
-1868
lines changed

22 files changed

+2180
-1868
lines changed

docs/changelog/135897.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 135897
2+
summary: Apply source excludes early when retrieving the `_inference_fields`
3+
area: Search
4+
type: bug
5+
issues: []

docs/changelog/135901.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 135901
2+
summary: Add support for dot-separated attribute names (e.g. `foo.bar`) and for parameters (e.g. `??my_param`) in FUSE GROUP BY
3+
area: ES|QL
4+
type: bug
5+
issues: []

muted-tests.yml

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -504,9 +504,6 @@ tests:
504504
- class: org.elasticsearch.repositories.blobstore.testkit.analyze.MinioRepositoryAnalysisRestIT
505505
method: testRepositoryAnalysis
506506
issue: https://github.com/elastic/elasticsearch/issues/134853
507-
- class: org.elasticsearch.xpack.esql.action.CrossClusterAsyncQueryStopIT
508-
method: testStopQueryInlinestats
509-
issue: https://github.com/elastic/elasticsearch/issues/134854
510507
- class: org.elasticsearch.xpack.esql.action.CrossClusterCancellationIT
511508
method: testCancelSkipUnavailable
512509
issue: https://github.com/elastic/elasticsearch/issues/134865
@@ -522,9 +519,6 @@ tests:
522519
- class: org.elasticsearch.xpack.esql.qa.mixed.MixedClusterEsqlSpecIT
523520
method: test {csv-spec:stats.CountDistinctWithConditions}
524521
issue: https://github.com/elastic/elasticsearch/issues/134993
525-
- class: org.elasticsearch.xpack.esql.action.CrossClusterAsyncQueryStopIT
526-
method: testStopQueryInlineStats
527-
issue: https://github.com/elastic/elasticsearch/issues/135032
528522
- class: org.elasticsearch.xpack.esql.ccq.MultiClusterSpecIT
529523
method: test {csv-spec:fork.ForkBeforeStatsWithWhere}
530524
issue: https://github.com/elastic/elasticsearch/issues/135041
@@ -678,6 +672,42 @@ tests:
678672
- class: org.elasticsearch.upgrades.FullClusterRestartIT
679673
method: testOperationBasedRecovery {cluster=UPGRADED}
680674
issue: https://github.com/elastic/elasticsearch/issues/135944
675+
- class: org.elasticsearch.upgrades.FullClusterRestartIT
676+
method: testRomanianAnalyzerBWC {cluster=UPGRADED}
677+
issue: https://github.com/elastic/elasticsearch/issues/135948
678+
- class: org.elasticsearch.upgrades.FullClusterRestartIT
679+
method: testEmptyShard {cluster=UPGRADED}
680+
issue: https://github.com/elastic/elasticsearch/issues/135951
681+
- class: org.elasticsearch.upgrades.FullClusterRestartIT
682+
method: testRollover {cluster=UPGRADED}
683+
issue: https://github.com/elastic/elasticsearch/issues/135952
684+
- class: org.elasticsearch.upgrades.FullClusterRestartIT
685+
method: testRecovery {cluster=UPGRADED}
686+
issue: https://github.com/elastic/elasticsearch/issues/135953
687+
- class: org.elasticsearch.upgrades.FullClusterRestartIT
688+
method: testNewReplicas {cluster=UPGRADED}
689+
issue: https://github.com/elastic/elasticsearch/issues/135956
690+
- class: org.elasticsearch.upgrades.FullClusterRestartIT
691+
method: testHistoryUUIDIsAdded {cluster=UPGRADED}
692+
issue: https://github.com/elastic/elasticsearch/issues/135957
693+
- class: org.elasticsearch.upgrades.FullClusterRestartIT
694+
method: testTurnOffTranslogRetentionAfterUpgraded {cluster=UPGRADED}
695+
issue: https://github.com/elastic/elasticsearch/issues/135958
696+
- class: org.elasticsearch.upgrades.FullClusterRestartIT
697+
method: testSoftDeletes {cluster=UPGRADED}
698+
issue: https://github.com/elastic/elasticsearch/issues/135959
699+
- class: org.elasticsearch.upgrades.FullClusterRestartIT
700+
method: testClusterState {cluster=UPGRADED}
701+
issue: https://github.com/elastic/elasticsearch/issues/135960
702+
- class: org.elasticsearch.upgrades.FullClusterRestartIT
703+
method: testShrink {cluster=UPGRADED}
704+
issue: https://github.com/elastic/elasticsearch/issues/135962
705+
- class: org.elasticsearch.upgrades.FullClusterRestartIT
706+
method: testSearchTimeSeriesMode {cluster=UPGRADED}
707+
issue: https://github.com/elastic/elasticsearch/issues/135963
708+
- class: org.elasticsearch.datastreams.DataStreamIndexSettingsProviderTests
709+
method: testGetAdditionalIndexSettings
710+
issue: https://github.com/elastic/elasticsearch/issues/135972
681711

682712
# Examples:
683713
#

server/src/main/java/org/elasticsearch/index/get/ShardGetService.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,14 @@ private static Boolean shouldExcludeVectorsFromSourceExplicit(FetchSourceContext
426426

427427
public static boolean shouldExcludeInferenceFieldsFromSource(IndexSettings indexSettings, FetchSourceContext fetchSourceContext) {
428428
var explicit = shouldExcludeInferenceFieldsFromSourceExplicit(fetchSourceContext);
429+
var filter = fetchSourceContext != null ? fetchSourceContext.filter() : null;
430+
if (filter != null) {
431+
if (filter.isPathFiltered(InferenceMetadataFieldsMapper.NAME, true)) {
432+
return true;
433+
} else if (filter.isExplicitlyIncluded(InferenceMetadataFieldsMapper.NAME)) {
434+
return false;
435+
}
436+
}
429437
return explicit != null ? explicit : INDEX_MAPPING_EXCLUDE_SOURCE_VECTORS_SETTING.get(indexSettings.getSettings());
430438
}
431439

server/src/main/java/org/elasticsearch/search/fetch/subphase/FetchSourcePhase.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.elasticsearch.search.lookup.Source;
2020
import org.elasticsearch.search.lookup.SourceFilter;
2121

22+
import java.util.HashMap;
2223
import java.util.Map;
2324

2425
public final class FetchSourcePhase implements FetchSubPhase {
@@ -99,6 +100,10 @@ private Source replaceInferenceMetadataFields(SearchHit hit, Source source) {
99100
return source;
100101
}
101102
var newSource = source.source();
103+
if (newSource instanceof HashMap == false) {
104+
// the map is not mutable
105+
newSource = new HashMap<>(newSource);
106+
}
102107
newSource.put(InferenceMetadataFieldsMapper.NAME, field.getValues().get(0));
103108
return Source.fromMap(newSource, source.sourceContentType());
104109
}

x-pack/plugin/esql/compute/ann/src/main/java/org/elasticsearch/compute/ann/Evaluator.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,11 @@
4242
* into a warning and turn into a null value.
4343
*/
4444
Class<? extends Exception>[] warnExceptions() default {};
45+
46+
/**
47+
* Automatically evaluate each position to null if it is null on all the
48+
* blocks. Setting this to {@code false} requires block parameters, like
49+
* {@code static boolean process(@Position int position, LongBlock field1, LongBlock field2)}
50+
*/
51+
boolean allNullsIsNull() default true;
4552
}

x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,15 @@ public class EvaluatorImplementer {
5151
private final ProcessFunction processFunction;
5252
private final ClassName implementation;
5353
private final boolean processOutputsMultivalued;
54+
private final boolean allNullsIsNull;
5455

5556
public EvaluatorImplementer(
5657
Elements elements,
5758
javax.lang.model.util.Types types,
5859
ExecutableElement processFunction,
5960
String extraName,
60-
List<TypeMirror> warnExceptions
61+
List<TypeMirror> warnExceptions,
62+
boolean allNullsIsNull
6163
) {
6264
this.declarationType = (TypeElement) processFunction.getEnclosingElement();
6365
this.processFunction = new ProcessFunction(types, processFunction, warnExceptions);
@@ -66,7 +68,8 @@ public EvaluatorImplementer(
6668
elements.getPackageOf(declarationType).toString(),
6769
declarationType.getSimpleName() + extraName + "Evaluator"
6870
);
69-
this.processOutputsMultivalued = this.processFunction.hasBlockType && (this.processFunction.builderArg != null);
71+
this.processOutputsMultivalued = this.processFunction.hasBlockType;
72+
this.allNullsIsNull = allNullsIsNull;
7073
}
7174

7275
public JavaFile sourceFile() {
@@ -131,7 +134,7 @@ private MethodSpec ctor() {
131134
MethodSpec.Builder builder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
132135
builder.addParameter(SOURCE, "source");
133136
builder.addStatement("this.source = source");
134-
processFunction.args.stream().forEach(a -> a.implementCtor(builder));
137+
processFunction.args.forEach(a -> a.implementCtor(builder));
135138
builder.addParameter(DRIVER_CONTEXT, "driverContext");
136139
builder.addStatement("this.driverContext = driverContext");
137140
return builder.build();
@@ -140,15 +143,15 @@ private MethodSpec ctor() {
140143
private MethodSpec eval() {
141144
MethodSpec.Builder builder = MethodSpec.methodBuilder("eval").addAnnotation(Override.class);
142145
builder.addModifiers(Modifier.PUBLIC).returns(BLOCK).addParameter(PAGE, "page");
143-
processFunction.args.stream().forEach(a -> a.evalToBlock(builder));
146+
processFunction.args.forEach(a -> a.evalToBlock(builder));
144147
String invokeBlockEval = invokeRealEval(true);
145148
if (processOutputsMultivalued) {
146149
builder.addStatement(invokeBlockEval);
147150
} else {
148-
processFunction.args.stream().forEach(a -> a.resolveVectors(builder, invokeBlockEval));
151+
processFunction.args.forEach(a -> a.resolveVectors(builder, invokeBlockEval));
149152
builder.addStatement(invokeRealEval(false));
150153
}
151-
processFunction.args.stream().forEach(a -> a.closeEvalToBlock(builder));
154+
processFunction.args.forEach(a -> a.closeEvalToBlock(builder));
152155
return builder.build();
153156
}
154157

@@ -157,7 +160,7 @@ private String invokeRealEval(boolean blockStyle) {
157160

158161
String params = processFunction.args.stream()
159162
.map(a -> a.paramName(blockStyle))
160-
.filter(a -> a != null)
163+
.filter(Objects::nonNull)
161164
.collect(Collectors.joining(", "));
162165
if (params.length() > 0) {
163166
builder.append(", ");
@@ -189,23 +192,23 @@ private MethodSpec realEval(boolean blockStyle) {
189192
buildFromFactory(builderType)
190193
);
191194
{
192-
processFunction.args.stream().forEach(a -> {
195+
processFunction.args.forEach(a -> {
193196
if (a.paramName(blockStyle) != null) {
194197
builder.addParameter(a.dataType(blockStyle), a.paramName(blockStyle));
195198
}
196199
});
197200

198-
processFunction.args.stream().forEach(a -> a.createScratch(builder));
201+
processFunction.args.forEach(a -> a.createScratch(builder));
199202

200203
builder.beginControlFlow("position: for (int p = 0; p < positionCount; p++)");
201204
{
202205
if (blockStyle) {
203206
if (processOutputsMultivalued == false) {
204-
processFunction.args.stream().forEach(a -> a.skipNull(builder));
205-
} else {
207+
processFunction.args.forEach(a -> a.skipNull(builder));
208+
} else if (allNullsIsNull) {
206209
builder.addStatement("boolean allBlocksAreNulls = true");
207210
// allow block type inputs to be null
208-
processFunction.args.stream().forEach(a -> a.allBlocksAreNull(builder));
211+
processFunction.args.forEach(a -> a.allBlocksAreNull(builder));
209212

210213
builder.beginControlFlow("if (allBlocksAreNulls)");
211214
{
@@ -214,25 +217,30 @@ private MethodSpec realEval(boolean blockStyle) {
214217
}
215218
builder.endControlFlow();
216219
}
220+
} else {
221+
assert allNullsIsNull : "allNullsIsNull == false is only supported for block style.";
217222
}
218-
processFunction.args.stream().forEach(a -> a.read(builder, blockStyle));
223+
processFunction.args.forEach(a -> a.read(builder, blockStyle));
219224

220225
StringBuilder pattern = new StringBuilder();
221226
List<Object> args = new ArrayList<>();
222227
pattern.append("$T.$N(");
223228
args.add(declarationType);
224229
args.add(processFunction.function.getSimpleName());
225-
processFunction.args.stream().forEach(a -> {
226-
if (args.size() > 2) {
227-
pattern.append(", ");
228-
}
229-
a.buildInvocation(pattern, args, blockStyle);
230-
});
230+
pattern.append(processFunction.args.stream().map(argument -> {
231+
var invocation = new StringBuilder();
232+
argument.buildInvocation(invocation, args, blockStyle);
233+
return invocation.toString();
234+
}).collect(Collectors.joining(", ")));
231235
pattern.append(")");
232236
String builtPattern;
233237
if (processFunction.builderArg == null) {
234-
builtPattern = vectorize ? "result.$L(p, " + pattern + ")" : "result.$L(" + pattern + ")";
235-
args.add(0, processFunction.appendMethod());
238+
if (vectorize) {
239+
builtPattern = "result.$L(p, " + pattern + ")";
240+
} else {
241+
builtPattern = "result.$L(" + pattern + ")";
242+
}
243+
args.addFirst(processFunction.appendMethod());
236244
} else {
237245
builtPattern = pattern.toString();
238246
}
@@ -246,7 +254,7 @@ private MethodSpec realEval(boolean blockStyle) {
246254
String catchPattern = "catch ("
247255
+ processFunction.warnExceptions.stream().map(m -> "$T").collect(Collectors.joining(" | "))
248256
+ " e)";
249-
builder.nextControlFlow(catchPattern, processFunction.warnExceptions.stream().map(m -> TypeName.get(m)).toArray());
257+
builder.nextControlFlow(catchPattern, processFunction.warnExceptions.stream().map(TypeName::get).toArray());
250258
builder.addStatement("warnings().registerException(e)");
251259
builder.addStatement("result.appendNull()");
252260
builder.endControlFlow();
@@ -282,7 +290,7 @@ private TypeSpec factory() {
282290
builder.addModifiers(Modifier.STATIC);
283291

284292
builder.addField(SOURCE, "source", Modifier.PRIVATE, Modifier.FINAL);
285-
processFunction.args.stream().forEach(a -> a.declareFactoryField(builder));
293+
processFunction.args.forEach(a -> a.declareFactoryField(builder));
286294

287295
builder.addMethod(processFunction.factoryCtor());
288296
builder.addMethod(processFunction.factoryGet(implementation));
@@ -371,7 +379,7 @@ MethodSpec factoryCtor() {
371379
MethodSpec.Builder builder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
372380
builder.addParameter(SOURCE, "source");
373381
builder.addStatement("this.source = source");
374-
args.stream().forEach(a -> a.implementFactoryCtor(builder));
382+
args.forEach(a -> a.implementFactoryCtor(builder));
375383
return builder.build();
376384
}
377385

x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorProcessor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv
8282
env.getTypeUtils(),
8383
(ExecutableElement) evaluatorMethod,
8484
evaluatorAnn.extraName(),
85-
warnExceptionsTypes
85+
warnExceptionsTypes,
86+
evaluatorAnn.allNullsIsNull()
8687
).sourceFile(),
8788
env
8889
);

x-pack/plugin/esql/qa/testFixtures/src/main/resources/fuse.csv-spec

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,33 @@ _score:double | new_fork:keyword | _id:keyword
281281
0.01587 | fork1 | 26
282282
;
283283

284+
fuseWithRrfAndDiscriminatorColumnWithDots
285+
required_capability: fork_v9
286+
required_capability: fuse_v6
287+
required_capability: semantic_text_field_caps
288+
required_capability: metadata_score
289+
required_capability: dots_in_fuse
290+
291+
FROM books METADATA _id, _index, _score
292+
| FORK ( WHERE title:"Tolkien" | SORT _score, _id DESC | LIMIT 3)
293+
( WHERE author:"Tolkien" | SORT _score, _id DESC | LIMIT 3)
294+
| EVAL new.fork = _fork
295+
| DROP _fork
296+
| FUSE rrf GROUP BY new.fork
297+
| SORT _score DESC, _id, _index
298+
| EVAL new.fork = mv_sort(new.fork)
299+
| EVAL _score = round(_score, 5)
300+
| KEEP _score, new.fork, _id
301+
;
302+
303+
_score:double | new.fork:keyword | _id:keyword
304+
0.03279 | [fork1, fork2] | 4
305+
0.01613 | fork1 | 56
306+
0.01613 | fork2 | 60
307+
0.01587 | fork2 | 1
308+
0.01587 | fork1 | 26
309+
;
310+
284311
fuseWithRrfAndKeyColumns
285312
required_capability: fork_v9
286313
required_capability: fuse_v6

x-pack/plugin/esql/src/internalClusterTest/java/org/elasticsearch/xpack/esql/action/CrossClusterAsyncQueryStopIT.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,9 +314,13 @@ public void testStopQueryInlineStats() throws Exception {
314314
assertThat(asyncResponse.columns().size(), equalTo(2));
315315
AtomicInteger i = new AtomicInteger(0);
316316
asyncResponse.values().forEachRemaining(row -> {
317-
// We will have all rows here but total will be null since we stopped the inline stats before it could complete
318-
assertThat(row.next(), equalTo(null));
319317
var v = row.next();
318+
// The sum could be null, if the stats did not manage to compute anything before being stopped
319+
// Or it could be 45L if it managed to add 0-9
320+
if (v != null) {
321+
assertThat((long) v, equalTo(45L));
322+
}
323+
v = row.next();
320324
if (v != null) {
321325
assertThat((long) v, lessThanOrEqualTo(10L));
322326
}

0 commit comments

Comments
 (0)