Skip to content

Commit 4af9812

Browse files
committed
Fix array_index_out_of_bounds_exception with wildcard and aggregations
Signed-off-by: Shawn Qiang <814238703@qq.com>
1 parent 4b9021f commit 4af9812

File tree

2 files changed

+11
-7
lines changed

2 files changed

+11
-7
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6767
- Fix ShardSearchFailure in transport-grpc ([#20641](https://github.com/opensearch-project/OpenSearch/pull/20641))
6868
- Fix TLS cert hot-reload for Arrow Flight transport ([#20732](https://github.com/opensearch-project/OpenSearch/pull/20732))
6969
- Fix misleading heap usage cancellation message in SearchBackpressureService ([#20779](https://github.com/opensearch-project/OpenSearch/pull/20779))
70-
- - Delegate getMin/getMax methods for ExitableTerms ([#20775](https://github.com/opensearch-project/OpenSearch/pull/20775))
70+
- Delegate getMin/getMax methods for ExitableTerms ([#20775](https://github.com/opensearch-project/OpenSearch/pull/20775))
7171
- Fix terms lookup subquery fetch limit reading from non-existent index setting instead of cluster `max_clause_count` ([#20823](https://github.com/opensearch-project/OpenSearch/pull/20823))
72+
- Fix array_index_out_of_bounds_exception with wildcard and aggregations ([#20842](https://github.com/opensearch-project/OpenSearch/pull/20842))
7273

7374
### Dependencies
7475
- Bump shadow-gradle-plugin from 8.3.9 to 9.3.1 ([#20569](https://github.com/opensearch-project/OpenSearch/pull/20569))

server/src/main/java/org/opensearch/index/mapper/WildcardFieldMapper.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ static class WildcardMatchingQuery extends Query {
743743
private final Query firstPhaseQuery;
744744
private final Predicate<String> secondPhaseMatcher;
745745
private final String patternString; // For toString
746-
private final ValueFetcher valueFetcher;
746+
private final Supplier<ValueFetcher> valueFetcherSupplier;
747747
private final SearchLookup searchLookup;
748748

749749
WildcardMatchingQuery(String fieldName, Query firstPhaseQuery, String patternString) {
@@ -764,10 +764,10 @@ public WildcardMatchingQuery(
764764
this.patternString = Objects.requireNonNull(patternString);
765765
if (context != null) {
766766
this.searchLookup = context.lookup();
767-
this.valueFetcher = fieldType.valueFetcher(context, context.lookup(), null);
767+
this.valueFetcherSupplier = () -> fieldType.valueFetcher(context, context.lookup(), null);
768768
} else {
769769
this.searchLookup = null;
770-
this.valueFetcher = null;
770+
this.valueFetcherSupplier = null;
771771
}
772772
}
773773

@@ -776,14 +776,14 @@ private WildcardMatchingQuery(
776776
Query firstPhaseQuery,
777777
Predicate<String> secondPhaseMatcher,
778778
String patternString,
779-
ValueFetcher valueFetcher,
779+
Supplier<ValueFetcher> valueFetcherSupplier,
780780
SearchLookup searchLookup
781781
) {
782782
this.fieldName = fieldName;
783783
this.firstPhaseQuery = firstPhaseQuery;
784784
this.secondPhaseMatcher = secondPhaseMatcher;
785785
this.patternString = patternString;
786-
this.valueFetcher = valueFetcher;
786+
this.valueFetcherSupplier = valueFetcherSupplier;
787787
this.searchLookup = searchLookup;
788788
}
789789

@@ -821,7 +821,7 @@ public Query rewrite(IndexSearcher indexSearcher) throws IOException {
821821
rewriteFirstPhase,
822822
secondPhaseMatcher,
823823
patternString,
824-
valueFetcher,
824+
valueFetcherSupplier,
825825
searchLookup
826826
);
827827
}
@@ -844,6 +844,9 @@ public Scorer get(long leadCost) throws IOException {
844844
Scorer approximateScorer = firstPhaseSupplier.get(leadCost);
845845
DocIdSetIterator approximation = approximateScorer.iterator();
846846
LeafSearchLookup leafSearchLookup = searchLookup.getLeafSearchLookup(context);
847+
// Create a new ValueFetcher per thread.
848+
// ValueFetcher.setNextReader is not thread safe.
849+
final ValueFetcher valueFetcher = valueFetcherSupplier.get();
847850
valueFetcher.setNextReader(context);
848851

849852
TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator(approximation) {

0 commit comments

Comments
 (0)