Skip to content

Commit 112bb00

Browse files
authored
Merge branch 'main' into pabloem-copy-sign
2 parents ea553b5 + 080a0cd commit 112bb00

File tree

40 files changed

+976
-161
lines changed

40 files changed

+976
-161
lines changed

build-tools-internal/src/test/java/org/elasticsearch/gradle/internal/release/ReleaseNotesGeneratorTest.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,14 @@
2020

2121
import static org.elasticsearch.gradle.internal.release.GenerateReleaseNotesTask.getSortedBundlesWithUniqueChangelogs;
2222
import static org.hamcrest.Matchers.equalTo;
23+
import static org.junit.Assert.assertFalse;
2324
import static org.junit.Assert.assertThat;
2425

2526
public class ReleaseNotesGeneratorTest {
2627

28+
// Temporarily set this to `true` to regenerate test output files when they need to be updated
29+
private final boolean UPDATE_EXPECTED_OUTPUT = false;
30+
2731
private static final List<String> CHANGE_TYPES = List.of(
2832
"breaking",
2933
"breaking-java",
@@ -78,8 +82,9 @@ public void testTemplate(String templateFilename, String outputFilename) throws
7882

7983
public void testTemplate(String templateFilename, String outputFilename, List<ChangelogBundle> bundles) throws Exception {
8084
// given:
85+
final String outputFile = "/org/elasticsearch/gradle/internal/release/ReleaseNotesGeneratorTest." + outputFilename;
8186
final String template = getResource("/templates/" + templateFilename);
82-
final String expectedOutput = getResource("/org/elasticsearch/gradle/internal/release/ReleaseNotesGeneratorTest." + outputFilename);
87+
final String expectedOutput = getResource(outputFile);
8388

8489
if (bundles == null) {
8590
bundles = getBundles();
@@ -91,7 +96,12 @@ public void testTemplate(String templateFilename, String outputFilename, List<Ch
9196
final String actualOutput = ReleaseNotesGenerator.generateFile(template, bundles);
9297

9398
// then:
94-
assertThat(actualOutput, equalTo(expectedOutput));
99+
if (UPDATE_EXPECTED_OUTPUT) {
100+
writeResource(outputFile, actualOutput);
101+
assertFalse("UPDATE_EXPECTED_OUTPUT should be set back to false after updating output", UPDATE_EXPECTED_OUTPUT);
102+
} else {
103+
assertThat(actualOutput, equalTo(expectedOutput));
104+
}
95105
}
96106

97107
private List<ChangelogBundle> getBundles() {
@@ -176,4 +186,9 @@ private ChangelogEntry makeHighlightsEntry(int pr, boolean notable) {
176186
private String getResource(String name) throws Exception {
177187
return Files.readString(Paths.get(Objects.requireNonNull(this.getClass().getResource(name)).toURI()), StandardCharsets.UTF_8);
178188
}
189+
190+
private void writeResource(String name, String contents) throws Exception {
191+
String path = "src/test/resources" + name;
192+
Files.writeString(Paths.get(path), contents);
193+
}
179194
}

build-tools-internal/src/test/resources/org/elasticsearch/gradle/internal/release/ReleaseNotesGeneratorTest.index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ To check for security updates, go to [Security announcements for the Elastic sta
2020
% ### Fixes [elasticsearch-next-fixes]
2121
% *
2222

23+
## 9.1.0 [elasticsearch-9.1.0-release-notes]
2324
```{applies_to}
2425
stack: coming 9.1.0
2526
```
26-
## 9.1.0 [elasticsearch-9.1.0-release-notes]
2727

2828
### Highlights [elasticsearch-9.1.0-highlights]
2929

@@ -47,10 +47,10 @@ Search:
4747
* [#52](https://github.com/elastic/elasticsearch/pull/52)
4848

4949

50+
## 9.0.10 [elasticsearch-9.0.10-release-notes]
5051
```{applies_to}
5152
stack: coming 9.0.10
5253
```
53-
## 9.0.10 [elasticsearch-9.0.10-release-notes]
5454

5555
### Features and enhancements [elasticsearch-9.0.10-features-enhancements]
5656

build-tools-internal/src/test/resources/org/elasticsearch/gradle/internal/release/ReleaseNotesGeneratorTest.index.no-highlights.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ To check for security updates, go to [Security announcements for the Elastic sta
2020
% ### Fixes [elasticsearch-next-fixes]
2121
% *
2222

23+
## 9.0.10 [elasticsearch-9.0.10-release-notes]
2324
```{applies_to}
2425
stack: coming 9.0.10
2526
```
26-
## 9.0.10 [elasticsearch-9.0.10-release-notes]
2727

2828
### Features and enhancements [elasticsearch-9.0.10-features-enhancements]
2929

docs/changelog/127968.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 127968
2+
summary: "Enable sort optimization on int, short and byte fields"
3+
area: Search
4+
type: enhancement
5+
issues:
6+
- 127965

docs/changelog/128036.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 128036
2+
summary: Fix inner hits + aggregations concurrency bug
3+
area: Search
4+
type: bug
5+
issues:
6+
- 122419

modules/parent-join/src/internalClusterTest/java/org/elasticsearch/join/query/InnerHitsIT.java

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import org.elasticsearch.script.ScriptType;
2727
import org.elasticsearch.search.SearchHit;
2828
import org.elasticsearch.search.SearchHits;
29+
import org.elasticsearch.search.aggregations.AggregationBuilder;
30+
import org.elasticsearch.search.aggregations.metrics.TopHits;
2931
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
3032
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
3133
import org.elasticsearch.search.sort.FieldSortBuilder;
@@ -51,6 +53,7 @@
5153
import static org.elasticsearch.index.seqno.SequenceNumbers.UNASSIGNED_SEQ_NO;
5254
import static org.elasticsearch.join.query.JoinQueryBuilders.hasChildQuery;
5355
import static org.elasticsearch.join.query.JoinQueryBuilders.hasParentQuery;
56+
import static org.elasticsearch.search.aggregations.AggregationBuilders.topHits;
5457
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
5558
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
5659
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCountAndNoFailures;
@@ -64,6 +67,7 @@
6467
import static org.hamcrest.Matchers.containsString;
6568
import static org.hamcrest.Matchers.equalTo;
6669
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
70+
import static org.hamcrest.Matchers.lessThanOrEqualTo;
6771
import static org.hamcrest.Matchers.notNullValue;
6872
import static org.hamcrest.Matchers.nullValue;
6973

@@ -698,4 +702,68 @@ public void testTooHighResultWindow() {
698702
)
699703
);
700704
}
705+
706+
public void testTopHitsOnParentChild() throws Exception {
707+
assertAcked(
708+
prepareCreate("idx").setMapping(
709+
jsonBuilder().startObject()
710+
.startObject("_doc")
711+
.startObject("properties")
712+
.startObject("id")
713+
.field("type", "keyword")
714+
.endObject()
715+
.startObject("join_field")
716+
.field("type", "join")
717+
.startObject("relations")
718+
.field("parent", new String[] { "child1", "child2" })
719+
.endObject()
720+
.endObject()
721+
.endObject()
722+
.endObject()
723+
.endObject()
724+
)
725+
);
726+
ensureGreen("idx");
727+
728+
List<IndexRequestBuilder> requestBuilders = new ArrayList<>();
729+
int numDocs = scaledRandomIntBetween(10, 100);
730+
int child1 = 0;
731+
int child2 = 0;
732+
int[] child1InnerObjects = new int[numDocs];
733+
int[] child2InnerObjects = new int[numDocs];
734+
for (int parent = 0; parent < numDocs; parent++) {
735+
String parentId = String.format(Locale.ENGLISH, "p_%03d", parent);
736+
requestBuilders.add(createIndexRequest("idx", "parent", parentId, null));
737+
738+
int numChildDocs = child1InnerObjects[parent] = scaledRandomIntBetween(1, numDocs);
739+
int limit = child1 + numChildDocs;
740+
for (; child1 < limit; child1++) {
741+
requestBuilders.add(createIndexRequest("idx", "child1", String.format(Locale.ENGLISH, "c1_%04d", child1), parentId));
742+
}
743+
numChildDocs = child2InnerObjects[parent] = scaledRandomIntBetween(1, numDocs);
744+
limit = child2 + numChildDocs;
745+
for (; child2 < limit; child2++) {
746+
requestBuilders.add(createIndexRequest("idx", "child2", String.format(Locale.ENGLISH, "c2_%04d", child2), parentId));
747+
}
748+
}
749+
750+
indexRandom(true, requestBuilders);
751+
ensureSearchable();
752+
753+
QueryBuilder hasChildQuery = hasChildQuery("child2", matchAllQuery(), ScoreMode.None).innerHit(new InnerHitBuilder().setSize(2));
754+
AggregationBuilder topHitsAgg = topHits("top-children").size(3);
755+
756+
assertNoFailuresAndResponse(prepareSearch("idx").setQuery(hasChildQuery).addAggregation(topHitsAgg), response -> {
757+
assertHitCount(response, numDocs);
758+
759+
TopHits topHits = response.getAggregations().get("top-children");
760+
SearchHits hits = topHits.getHits();
761+
assertThat(hits.getHits().length, equalTo(3));
762+
763+
for (SearchHit hit : hits) {
764+
SearchHits innerHits = hit.getInnerHits().get("child2");
765+
assertThat(innerHits.getHits().length, lessThanOrEqualTo(2));
766+
}
767+
});
768+
}
701769
}

modules/parent-join/src/main/java/org/elasticsearch/join/query/ParentChildInnerHitContextBuilder.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,35 @@ static final class JoinFieldInnerHitSubContext extends InnerHitsContext.InnerHit
8888
private final String typeName;
8989
private final boolean fetchChildInnerHits;
9090
private final Joiner joiner;
91+
private final SearchExecutionContext searchExecutionContext;
9192

9293
JoinFieldInnerHitSubContext(String name, SearchContext context, String typeName, boolean fetchChildInnerHits, Joiner joiner) {
9394
super(name, context);
9495
this.typeName = typeName;
9596
this.fetchChildInnerHits = fetchChildInnerHits;
9697
this.joiner = joiner;
98+
this.searchExecutionContext = null;
99+
}
100+
101+
JoinFieldInnerHitSubContext(
102+
JoinFieldInnerHitSubContext joinFieldInnerHitSubContext,
103+
SearchExecutionContext searchExecutionContext
104+
) {
105+
super(joinFieldInnerHitSubContext);
106+
this.typeName = joinFieldInnerHitSubContext.typeName;
107+
this.fetchChildInnerHits = joinFieldInnerHitSubContext.fetchChildInnerHits;
108+
this.joiner = joinFieldInnerHitSubContext.joiner;
109+
this.searchExecutionContext = searchExecutionContext;
110+
}
111+
112+
@Override
113+
public JoinFieldInnerHitSubContext copyWithSearchExecutionContext(SearchExecutionContext searchExecutionContext) {
114+
return new JoinFieldInnerHitSubContext(this, searchExecutionContext);
115+
}
116+
117+
@Override
118+
public SearchExecutionContext getSearchExecutionContext() {
119+
return searchExecutionContext != null ? searchExecutionContext : super.getSearchExecutionContext();
97120
}
98121

99122
@Override

muted-tests.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -534,12 +534,6 @@ tests:
534534
- class: org.elasticsearch.packaging.test.DockerTests
535535
method: test040JavaUsesTheOsProvidedKeystore
536536
issue: https://github.com/elastic/elasticsearch/issues/128230
537-
- class: org.elasticsearch.gradle.internal.release.ReleaseNotesGeneratorTest
538-
method: generateFile_index_rendersCorrectMarkup
539-
issue: https://github.com/elastic/elasticsearch/issues/128772
540-
- class: org.elasticsearch.gradle.internal.release.ReleaseNotesGeneratorTest
541-
method: generateFile_index_noHighlights_rendersCorrectMarkup
542-
issue: https://github.com/elastic/elasticsearch/issues/128773
543537
- class: org.elasticsearch.xpack.rank.rrf.LinearRankClientYamlTestSuiteIT
544538
method: test {yaml=linear/10_linear_retriever/should normalize initial scores with l2_norm}
545539
issue: https://github.com/elastic/elasticsearch/issues/128774
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
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", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.upgrades;
11+
12+
import com.carrotsearch.randomizedtesting.annotations.Name;
13+
14+
import org.elasticsearch.client.Request;
15+
import org.elasticsearch.common.settings.Settings;
16+
17+
import java.util.List;
18+
import java.util.Map;
19+
20+
/**
21+
* Tests that index sorting works correctly after a rolling upgrade.
22+
*/
23+
public class IndexSortUpgradeIT extends AbstractRollingUpgradeTestCase {
24+
25+
public IndexSortUpgradeIT(@Name("upgradedNodes") int upgradedNodes) {
26+
super(upgradedNodes);
27+
}
28+
29+
@SuppressWarnings("unchecked")
30+
public void testIndexSortForNumericTypes() throws Exception {
31+
record IndexConfig(String indexName, String fieldName, String fieldType) {}
32+
var configs = new IndexConfig[] {
33+
new IndexConfig("index_byte", "byte_field", "byte"),
34+
new IndexConfig("index_short", "short_field", "short"),
35+
new IndexConfig("index_int", "int_field", "integer") };
36+
37+
if (isOldCluster()) {
38+
int numShards = randomIntBetween(1, 3);
39+
for (var config : configs) {
40+
createIndex(
41+
config.indexName(),
42+
Settings.builder()
43+
.put("index.number_of_shards", numShards)
44+
.put("index.number_of_replicas", 0)
45+
.put("index.sort.field", config.fieldName())
46+
.put("index.sort.order", "desc")
47+
.build(),
48+
"""
49+
{
50+
"properties": {
51+
"%s": {
52+
"type": "%s"
53+
}
54+
}
55+
}
56+
""".formatted(config.fieldName(), config.fieldType())
57+
);
58+
}
59+
}
60+
61+
final int numDocs = randomIntBetween(10, 25);
62+
for (var config : configs) {
63+
var bulkRequest = new Request("POST", "/" + config.indexName() + "/_bulk");
64+
StringBuilder bulkBody = new StringBuilder();
65+
for (int i = 0; i < numDocs; i++) {
66+
bulkBody.append("{\"index\": {}}\n");
67+
bulkBody.append("{\"" + config.fieldName() + "\": ").append(i).append("}\n");
68+
}
69+
bulkRequest.setJsonEntity(bulkBody.toString());
70+
bulkRequest.addParameter("refresh", "true");
71+
var bulkResponse = client().performRequest(bulkRequest);
72+
assertOK(bulkResponse);
73+
74+
var searchRequest = new Request("GET", "/" + config.indexName() + "/_search");
75+
searchRequest.setJsonEntity("""
76+
{
77+
"query": {
78+
"match_all": {}
79+
},
80+
"sort": {
81+
"%s": {
82+
"order": "desc"
83+
}
84+
}
85+
}
86+
""".formatted(config.fieldName()));
87+
var searchResponse = client().performRequest(searchRequest);
88+
assertOK(searchResponse);
89+
var responseBody = entityAsMap(searchResponse);
90+
var hits = (List<Map<String, Object>>) ((Map<String, Object>) responseBody.get("hits")).get("hits");
91+
int previousValue = ((Number) ((List<Object>) hits.get(0).get("sort")).get(0)).intValue();
92+
;
93+
for (int i = 1; i < hits.size(); i++) {
94+
int currentValue = ((Number) ((List<Object>) hits.get(i).get("sort")).get(0)).intValue();
95+
assertTrue("Sort values are not in desc order ", previousValue >= currentValue);
96+
previousValue = currentValue;
97+
}
98+
}
99+
}
100+
}

0 commit comments

Comments
 (0)