Skip to content

Commit 212efd7

Browse files
Fix a race condition in Derived Field parsing from search request (#14445)
Signed-off-by: Rishabh Maurya <rishabhmaurya05@gmail.com>
1 parent 1da19d3 commit 212efd7

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
99
- [Remote Store] Rate limiter for remote store low priority uploads ([#14374](https://github.com/opensearch-project/OpenSearch/pull/14374/))
1010
- Apply the date histogram rewrite optimization to range aggregation ([#13865](https://github.com/opensearch-project/OpenSearch/pull/13865))
1111
- [Writable Warm] Add composite directory implementation and integrate it with FileCache ([12782](https://github.com/opensearch-project/OpenSearch/pull/12782))
12+
- Fix race condition while parsing derived fields from search definition ([14445](https://github.com/opensearch-project/OpenSearch/pull/14445))
1213

1314
### Dependencies
1415
- Bump `org.gradle.test-retry` from 1.5.8 to 1.5.9 ([#13442](https://github.com/opensearch-project/OpenSearch/pull/13442))

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

+27-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import org.opensearch.script.Script;
1616

1717
import java.io.IOException;
18+
import java.util.ArrayList;
19+
import java.util.Arrays;
1820
import java.util.HashMap;
1921
import java.util.HashSet;
2022
import java.util.List;
@@ -189,9 +191,10 @@ private void initDerivedFieldTypes(Map<String, Object> derivedFieldsObject, List
189191

190192
private Map<String, DerivedFieldType> getAllDerivedFieldTypeFromObject(Map<String, Object> derivedFieldObject) {
191193
Map<String, DerivedFieldType> derivedFieldTypes = new HashMap<>();
194+
// deep copy of derivedFieldObject is required as DocumentMapperParser modifies the map
192195
DocumentMapper documentMapper = queryShardContext.getMapperService()
193196
.documentMapperParser()
194-
.parse(DerivedFieldMapper.CONTENT_TYPE, derivedFieldObject);
197+
.parse(DerivedFieldMapper.CONTENT_TYPE, (Map) deepCopy(derivedFieldObject));
195198
if (documentMapper != null && documentMapper.mappers() != null) {
196199
for (Mapper mapper : documentMapper.mappers()) {
197200
if (mapper instanceof DerivedFieldMapper) {
@@ -226,4 +229,27 @@ private DerivedFieldType resolveUsingMappings(String name) {
226229
}
227230
return null;
228231
}
232+
233+
private static Object deepCopy(Object value) {
234+
if (value instanceof Map) {
235+
Map<?, ?> mapValue = (Map<?, ?>) value;
236+
Map<Object, Object> copy = new HashMap<>(mapValue.size());
237+
for (Map.Entry<?, ?> entry : mapValue.entrySet()) {
238+
copy.put(entry.getKey(), deepCopy(entry.getValue()));
239+
}
240+
return copy;
241+
} else if (value instanceof List) {
242+
List<?> listValue = (List<?>) value;
243+
List<Object> copy = new ArrayList<>(listValue.size());
244+
for (Object itemValue : listValue) {
245+
copy.add(deepCopy(itemValue));
246+
}
247+
return copy;
248+
} else if (value instanceof byte[]) {
249+
byte[] bytes = (byte[]) value;
250+
return Arrays.copyOf(bytes, bytes.length);
251+
} else {
252+
return value;
253+
}
254+
}
229255
}

0 commit comments

Comments
 (0)