Skip to content

Commit f93ad93

Browse files
committed
Fix array_index_out_of_bounds_exception with wildcard and aggregations (opensearch-project#20842)
Signed-off-by: Shawn Qiang <814238703@qq.com> (cherry picked from commit 0e2783c) Signed-off-by: Shawn Qiang <814238703@qq.com>
1 parent 3954541 commit f93ad93

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1515
### Fixed
1616
- Harden the circuit breaker and failure handle logic in query result consumer ([#19396](https://github.com/opensearch-project/OpenSearch/pull/19396))
1717
- Fix case insensitive and escaped query on wildcard ([#16827](https://github.com/opensearch-project/OpenSearch/pull/16827))
18+
- Fix array_index_out_of_bounds_exception with wildcard and aggregations ([#20842](https://github.com/opensearch-project/OpenSearch/pull/20842))
1819

1920
### Security
2021

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

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ static class WildcardMatchingQuery extends Query {
773773
private final Query firstPhaseQuery;
774774
private final Predicate<String> secondPhaseMatcher;
775775
private final String patternString; // For toString
776-
private final ValueFetcher valueFetcher;
776+
private final Supplier<ValueFetcher> valueFetcherSupplier;
777777
private final SearchLookup searchLookup;
778778

779779
WildcardMatchingQuery(String fieldName, Query firstPhaseQuery, String patternString) {
@@ -794,10 +794,10 @@ public WildcardMatchingQuery(
794794
this.patternString = Objects.requireNonNull(patternString);
795795
if (context != null) {
796796
this.searchLookup = context.lookup();
797-
this.valueFetcher = fieldType.valueFetcher(context, context.lookup(), null);
797+
this.valueFetcherSupplier = () -> fieldType.valueFetcher(context, context.lookup(), null);
798798
} else {
799799
this.searchLookup = null;
800-
this.valueFetcher = null;
800+
this.valueFetcherSupplier = null;
801801
}
802802
}
803803

@@ -806,14 +806,14 @@ private WildcardMatchingQuery(
806806
Query firstPhaseQuery,
807807
Predicate<String> secondPhaseMatcher,
808808
String patternString,
809-
ValueFetcher valueFetcher,
809+
Supplier<ValueFetcher> valueFetcherSupplier,
810810
SearchLookup searchLookup
811811
) {
812812
this.fieldName = fieldName;
813813
this.firstPhaseQuery = firstPhaseQuery;
814814
this.secondPhaseMatcher = secondPhaseMatcher;
815815
this.patternString = patternString;
816-
this.valueFetcher = valueFetcher;
816+
this.valueFetcherSupplier = valueFetcherSupplier;
817817
this.searchLookup = searchLookup;
818818
}
819819

@@ -851,7 +851,7 @@ public Query rewrite(IndexSearcher indexSearcher) throws IOException {
851851
rewriteFirstPhase,
852852
secondPhaseMatcher,
853853
patternString,
854-
valueFetcher,
854+
valueFetcherSupplier,
855855
searchLookup
856856
);
857857
}
@@ -884,6 +884,9 @@ public Scorer get(long leadCost) throws IOException {
884884
Scorer approximateScorer = firstPhaseSupplier.get(leadCost);
885885
DocIdSetIterator approximation = approximateScorer.iterator();
886886
LeafSearchLookup leafSearchLookup = searchLookup.getLeafSearchLookup(context);
887+
// Create a new ValueFetcher per thread.
888+
// ValueFetcher.setNextReader is not thread safe.
889+
final ValueFetcher valueFetcher = valueFetcherSupplier.get();
887890
valueFetcher.setNextReader(context);
888891

889892
TwoPhaseIterator twoPhaseIterator = new TwoPhaseIterator(approximation) {

0 commit comments

Comments
 (0)