Skip to content

Commit 72ad439

Browse files
authored
Merge branch 'main' into esql-test-cleanup
2 parents daf6381 + 285866e commit 72ad439

File tree

105 files changed

+436
-123
lines changed

Some content is hidden

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

105 files changed

+436
-123
lines changed

docs/changelog/131032.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pr: 131032
2+
summary: "Fix: `GET _synonyms` returns synonyms with empty rules"
3+
area: Relevance
4+
type: bug
5+
issues: []

docs/reference/query-languages/esql/limitations.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,6 @@ Work around this limitation by converting the field to single value with one of
250250
* CSV export from Discover shows no more than 10,000 rows. This limit only applies to the number of rows that are retrieved by the query and displayed in Discover. Queries and aggregations run on the full data set.
251251
* Querying many indices at once without any filters can cause an error in kibana which looks like `[esql] > Unexpected error from Elasticsearch: The content length (536885793) is bigger than the maximum allowed string (536870888)`. The response from {{esql}} is too long. Use [`DROP`](/reference/query-languages/esql/commands/processing-commands.md#esql-drop) or [`KEEP`](/reference/query-languages/esql/commands/processing-commands.md#esql-keep) to limit the number of fields returned.
252252

253+
## Known issues [esql-known-issues]
254+
255+
Refer to [Known issues](/release-notes/known-issues.md) for a list of known issues for {{esql}}.

docs/release-notes/known-issues.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,19 @@ mapped_pages:
88
Known issues are significant defects or limitations that may impact your implementation. These issues are actively being worked on and will be addressed in a future release. Review the Elasticsearch known issues to help you make informed decisions, such as upgrading to a new version.
99

1010
## 9.0.3 [elasticsearch-9.0.3-known-issues]
11-
A bug in the merge scheduler in Elasticsearch 9.0.3 may prevent shards from closing when there isn’t enough disk space to complete a merge. As a result, operations such as closing or relocating an index may hang until sufficient disk space becomes available.
11+
* A bug in the merge scheduler in Elasticsearch 9.0.3 may prevent shards from closing when there isn’t enough disk space to complete a merge. As a result, operations such as closing or relocating an index may hang until sufficient disk space becomes available.
1212
To mitigate this issue, the disk space checker is disabled by default in 9.0.3 by setting `indices.merge.disk.check_interval` to `0` seconds. Manually enabling this setting is not recommended.
1313

14-
This issue is planned to be fixed in future patch release [#129613](https://github.com/elastic/elasticsearch/pull/129613)
14+
This issue is planned to be fixed in future patch release [#129613](https://github.com/elastic/elasticsearch/pull/129613)
15+
16+
* A bug in the ES|QL STATS command may yield incorrect results. The bug only happens in very specific cases that follow this pattern: `STATS ... BY keyword1, keyword2`, i.e. the command must have exactly two grouping fields, both keywords, where the first field has high cardinality (more than 65k distinct values).
17+
18+
The bug is described in detail in [this issue](https://github.com/elastic/elasticsearch/issues/130644).
19+
The problem was introduced in 8.16.0 and [fixed](https://github.com/elastic/elasticsearch/pull/130705) in 8.17.9, 8.18.7, 9.0.4.
20+
21+
Possible workarounds include:
22+
* switching the order of the grouping keys (eg. `STATS ... BY keyword2, keyword1`, if the `keyword2` has a lower cardinality)
23+
* reducing the grouping key cardinality, by filtering out values before STATS
1524

1625
## 9.0.0 [elasticsearch-9.0.0-known-issues]
1726
* Elasticsearch on Windows might fail to start, or might forbid some file-related operations, when referencing paths with a case different from the one stored by the filesystem. Windows treats paths as case-insensitive, but the filesystem stores them with case. Entitlements, the new security system used by Elasticsearch, treat all paths as case-sensitive, and can therefore prevent access to a path that should be accessible.
@@ -40,3 +49,12 @@ This issue will be fixed in a future patch release (see [PR #126990](https://git
4049
DELETE _index_template/.watches
4150
POST /_watcher/_start
4251
```
52+
53+
* A bug in the ES|QL STATS command may yield incorrect results. The bug only happens in very specific cases that follow this pattern: `STATS ... BY keyword1, keyword2`, i.e. the command must have exactly two grouping fields, both keywords, where the first field has high cardinality (more than 65k distinct values).
54+
55+
The bug is described in detail in [this issue](https://github.com/elastic/elasticsearch/issues/130644).
56+
The problem was introduced in 8.16.0 and [fixed](https://github.com/elastic/elasticsearch/pull/130705) in 8.17.9, 8.18.7, 9.0.4.
57+
58+
Possible workarounds include:
59+
* switching the order of the grouping keys (eg. `STATS ... BY keyword2, keyword1`, if the `keyword2` has a lower cardinality)
60+
* reducing the grouping key cardinality, by filtering out values before STATS

muted-tests.yml

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -519,12 +519,6 @@ tests:
519519
- class: org.elasticsearch.xpack.esql.action.EsqlActionBreakerIT
520520
method: testTopNPushedToLucene
521521
issue: https://github.com/elastic/elasticsearch/issues/130505
522-
- class: org.elasticsearch.xpack.monitoring.exporter.http.HttpExporterTests
523-
method: testExporterWithHostOnly
524-
issue: https://github.com/elastic/elasticsearch/issues/130599
525-
- class: org.elasticsearch.xpack.monitoring.exporter.http.HttpExporterTests
526-
method: testCreateRestClient
527-
issue: https://github.com/elastic/elasticsearch/issues/130600
528522
- class: org.elasticsearch.xpack.esql.qa.multi_node.EsqlSpecIT
529523
method: test {match-operator.MatchWithMoreComplexDisjunctionAndConjunction SYNC}
530524
issue: https://github.com/elastic/elasticsearch/issues/130640
@@ -543,9 +537,6 @@ tests:
543537
- class: org.elasticsearch.xpack.esql.action.CrossClusterAsyncQueryStopIT
544538
method: testStopQueryLocal
545539
issue: https://github.com/elastic/elasticsearch/issues/121672
546-
- class: org.elasticsearch.xpack.esql.action.EsqlRemoteErrorWrapIT
547-
method: testThatRemoteErrorsAreWrapped
548-
issue: https://github.com/elastic/elasticsearch/issues/130794
549540
- class: org.elasticsearch.backwards.MixedClusterClientYamlTestSuiteIT
550541
method: test {p0=mtermvectors/10_basic/Tests catching other exceptions per item}
551542
issue: https://github.com/elastic/elasticsearch/issues/122414
@@ -567,6 +558,9 @@ tests:
567558
- class: org.elasticsearch.xpack.esql.action.EsqlActionBreakerIT
568559
method: testRowStatsProjectGroupByInt
569560
issue: https://github.com/elastic/elasticsearch/issues/131024
561+
- class: org.elasticsearch.common.util.concurrent.TaskExecutionTimeTrackingEsThreadPoolExecutorTests
562+
method: testMaxQueueLatency
563+
issue: https://github.com/elastic/elasticsearch/issues/131093
570564

571565
# Examples:
572566
#

rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/synonyms/40_synonyms_sets_get.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,33 @@ setup:
157157

158158
- match:
159159
count: 12
160+
161+
---
162+
"Return empty rule set":
163+
- requires:
164+
cluster_features: [ synonyms_set.get.return_empty_synonym_sets ]
165+
reason: "synonyms_set get api return empty synonym sets"
166+
167+
- do:
168+
synonyms.put_synonym:
169+
id: empty-synonyms
170+
body:
171+
synonyms_set: []
172+
173+
- do:
174+
synonyms.get_synonyms_sets: {}
175+
176+
- match:
177+
count: 4
178+
179+
- match:
180+
results:
181+
- synonyms_set: "empty-synonyms"
182+
count: 0
183+
- synonyms_set: "test-synonyms-1"
184+
count: 3
185+
- synonyms_set: "test-synonyms-2"
186+
count: 1
187+
- synonyms_set: "test-synonyms-3"
188+
count: 2
189+

server/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@
429429
org.elasticsearch.index.mapper.MapperFeatures,
430430
org.elasticsearch.index.IndexFeatures,
431431
org.elasticsearch.search.SearchFeatures,
432+
org.elasticsearch.synonyms.SynonymFeatures,
432433
org.elasticsearch.script.ScriptFeatures,
433434
org.elasticsearch.search.retriever.RetrieversFeatures,
434435
org.elasticsearch.action.admin.cluster.stats.ClusterStatsFeatures,
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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.synonyms;
11+
12+
import org.elasticsearch.features.FeatureSpecification;
13+
import org.elasticsearch.features.NodeFeature;
14+
15+
import java.util.Set;
16+
17+
public class SynonymFeatures implements FeatureSpecification {
18+
private static final NodeFeature RETURN_EMPTY_SYNONYM_SETS = new NodeFeature("synonyms_set.get.return_empty_synonym_sets");
19+
20+
@Override
21+
public Set<NodeFeature> getTestFeatures() {
22+
return Set.of(RETURN_EMPTY_SYNONYM_SETS);
23+
}
24+
}

server/src/main/java/org/elasticsearch/synonyms/SynonymsManagementAPIService.java

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@
5050
import org.elasticsearch.indices.SystemIndexDescriptor;
5151
import org.elasticsearch.rest.RestStatus;
5252
import org.elasticsearch.search.aggregations.BucketOrder;
53+
import org.elasticsearch.search.aggregations.bucket.filter.Filters;
54+
import org.elasticsearch.search.aggregations.bucket.filter.FiltersAggregationBuilder;
55+
import org.elasticsearch.search.aggregations.bucket.filter.FiltersAggregator;
5356
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
5457
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
5558
import org.elasticsearch.search.builder.SearchSourceBuilder;
@@ -94,6 +97,8 @@ public class SynonymsManagementAPIService {
9497
private static final int MAX_SYNONYMS_SETS = 10_000;
9598
private static final String SYNONYM_RULE_ID_FIELD = SynonymRule.ID_FIELD.getPreferredName();
9699
private static final String SYNONYM_SETS_AGG_NAME = "synonym_sets_aggr";
100+
private static final String RULE_COUNT_AGG_NAME = "rule_count";
101+
private static final String RULE_COUNT_FILTER_KEY = "synonym_rules";
97102
private static final int SYNONYMS_INDEX_MAPPINGS_VERSION = 1;
98103
public static final int INDEX_SEARCHABLE_TIMEOUT_SECONDS = 30;
99104
private final int maxSynonymsSets;
@@ -185,27 +190,45 @@ private static XContentBuilder mappings() {
185190
}
186191
}
187192

193+
/**
194+
* Returns all synonym sets with their rule counts, including empty synonym sets.
195+
* @param from The index of the first synonym set to return
196+
* @param size The number of synonym sets to return
197+
* @param listener The listener to return the synonym sets to
198+
*/
188199
public void getSynonymsSets(int from, int size, ActionListener<PagedResult<SynonymSetSummary>> listener) {
200+
BoolQueryBuilder synonymSetQuery = QueryBuilders.boolQuery()
201+
.should(QueryBuilders.termQuery(OBJECT_TYPE_FIELD, SYNONYM_SET_OBJECT_TYPE))
202+
.should(QueryBuilders.termQuery(OBJECT_TYPE_FIELD, SYNONYM_RULE_OBJECT_TYPE))
203+
.minimumShouldMatch(1);
204+
205+
// Aggregation query to count only synonym rules (excluding synonym set objects)
206+
FiltersAggregationBuilder ruleCountAggregation = new FiltersAggregationBuilder(
207+
RULE_COUNT_AGG_NAME,
208+
new FiltersAggregator.KeyedFilter(RULE_COUNT_FILTER_KEY, QueryBuilders.termQuery(OBJECT_TYPE_FIELD, SYNONYM_RULE_OBJECT_TYPE))
209+
);
210+
189211
client.prepareSearch(SYNONYMS_ALIAS_NAME)
190212
.setSize(0)
191213
// Retrieves aggregated synonym rules for each synonym set, excluding the synonym set object type
192-
.setQuery(QueryBuilders.termQuery(OBJECT_TYPE_FIELD, SYNONYM_RULE_OBJECT_TYPE))
214+
.setQuery(synonymSetQuery)
193215
.addAggregation(
194216
new TermsAggregationBuilder(SYNONYM_SETS_AGG_NAME).field(SYNONYMS_SET_FIELD)
195217
.order(BucketOrder.key(true))
196218
.size(maxSynonymsSets)
219+
.subAggregation(ruleCountAggregation)
197220
)
198221
.setPreference(Preference.LOCAL.type())
199222
.execute(new ActionListener<>() {
200223
@Override
201224
public void onResponse(SearchResponse searchResponse) {
202225
Terms termsAggregation = searchResponse.getAggregations().get(SYNONYM_SETS_AGG_NAME);
203226
List<? extends Terms.Bucket> buckets = termsAggregation.getBuckets();
204-
SynonymSetSummary[] synonymSetSummaries = buckets.stream()
205-
.skip(from)
206-
.limit(size)
207-
.map(bucket -> new SynonymSetSummary(bucket.getDocCount(), bucket.getKeyAsString()))
208-
.toArray(SynonymSetSummary[]::new);
227+
SynonymSetSummary[] synonymSetSummaries = buckets.stream().skip(from).limit(size).map(bucket -> {
228+
Filters ruleCountFilters = bucket.getAggregations().get(RULE_COUNT_AGG_NAME);
229+
Filters.Bucket ruleCountBucket = ruleCountFilters.getBucketByKey(RULE_COUNT_FILTER_KEY);
230+
return new SynonymSetSummary(ruleCountBucket.getDocCount(), bucket.getKeyAsString());
231+
}).toArray(SynonymSetSummary[]::new);
209232

210233
listener.onResponse(new PagedResult<>(buckets.size(), synonymSetSummaries));
211234
}

server/src/main/resources/META-INF/services/org.elasticsearch.features.FeatureSpecification

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ org.elasticsearch.rest.action.admin.cluster.GetSnapshotsFeatures
1414
org.elasticsearch.index.IndexFeatures
1515
org.elasticsearch.index.mapper.MapperFeatures
1616
org.elasticsearch.search.SearchFeatures
17+
org.elasticsearch.synonyms.SynonymFeatures
1718
org.elasticsearch.search.retriever.RetrieversFeatures
1819
org.elasticsearch.script.ScriptFeatures
1920
org.elasticsearch.cluster.routing.RoutingFeatures

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ private TypeSpec type() {
200200
builder.addMethod(ctor());
201201
builder.addMethod(intermediateStateDesc());
202202
builder.addMethod(intermediateBlockCount());
203-
builder.addMethod(prepareProcessPage());
203+
builder.addMethod(prepareProcessRawInputPage());
204204
for (ClassName groupIdClass : GROUP_IDS_CLASSES) {
205205
builder.addMethod(addRawInputLoop(groupIdClass, blockType(aggParam.type())));
206206
builder.addMethod(addRawInputLoop(groupIdClass, vectorType(aggParam.type())));
@@ -315,10 +315,10 @@ private MethodSpec intermediateBlockCount() {
315315
}
316316

317317
/**
318-
* Prepare to process a single page of results.
318+
* Prepare to process a single raw input page.
319319
*/
320-
private MethodSpec prepareProcessPage() {
321-
MethodSpec.Builder builder = MethodSpec.methodBuilder("prepareProcessPage");
320+
private MethodSpec prepareProcessRawInputPage() {
321+
MethodSpec.Builder builder = MethodSpec.methodBuilder("prepareProcessRawInputPage");
322322
builder.addAnnotation(Override.class).addModifiers(Modifier.PUBLIC).returns(GROUPING_AGGREGATOR_FUNCTION_ADD_INPUT);
323323
builder.addParameter(SEEN_GROUP_IDS, "seenGroupIds").addParameter(PAGE, "page");
324324

0 commit comments

Comments
 (0)