Skip to content

Commit 7ff4f3e

Browse files
authored
Fix propagation of dynamic mapping parameter when applying copy_to (#121109) (#121357)
(cherry picked from commit 1225b07) # Conflicts: # rest-api-spec/build.gradle
1 parent 0cd458a commit 7ff4f3e

File tree

5 files changed

+59
-7
lines changed

5 files changed

+59
-7
lines changed

docs/changelog/121109.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
pr: 121109
2+
summary: Fix propagation of dynamic mapping parameter when applying `copy_to`
3+
area: Mapping
4+
type: bug
5+
issues:
6+
- 113049
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
copy_to from object with dynamic strict to dynamic field:
3+
- requires:
4+
cluster_features: ["mapper.copy_to.dynamic_handling"]
5+
reason: requires a fix
6+
7+
- do:
8+
indices.create:
9+
index: test
10+
body:
11+
mappings:
12+
properties:
13+
one:
14+
dynamic: strict
15+
properties:
16+
k:
17+
type: keyword
18+
copy_to: two.k
19+
20+
- do:
21+
index:
22+
index: test
23+
id: 1
24+
refresh: true
25+
body:
26+
one:
27+
k: "hey"
28+
29+
- do:
30+
search:
31+
index: test
32+
body:
33+
docvalue_fields: [ "two.k.keyword" ]
34+
35+
- match:
36+
hits.hits.0._source:
37+
one:
38+
k: "hey"
39+
- match:
40+
hits.hits.0.fields:
41+
two.k.keyword: [ "hey" ]

server/src/main/java/org/elasticsearch/index/mapper/DocumentParserContext.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ private Wrapper(ObjectMapper parent, DocumentParserContext in) {
5050
this.in = in;
5151
}
5252

53+
// Used to create a copy_to context.
54+
// It is important to reset `dynamic` here since it is possible that we copy into a completely different object.
55+
private Wrapper(RootObjectMapper root, DocumentParserContext in) {
56+
super(root, ObjectMapper.Dynamic.getRootDynamic(in.mappingLookup()), in);
57+
this.in = in;
58+
}
59+
5360
@Override
5461
public Iterable<LuceneDocument> nonRootDocuments() {
5562
return in.nonRootDocuments();
@@ -711,6 +718,7 @@ in synthetic _source (to be consistent with stored _source).
711718

712719
ContentPath path = new ContentPath();
713720
XContentParser parser = DotExpandingXContentParser.expandDots(new CopyToParser(copyToField, parser()), path);
721+
714722
return new Wrapper(root(), this) {
715723
@Override
716724
public ContentPath path() {

server/src/main/java/org/elasticsearch/index/mapper/MapperFeatures.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ public Set<NodeFeature> getFeatures() {
6262
public static final NodeFeature META_FETCH_FIELDS_ERROR_CODE_CHANGED = new NodeFeature("meta_fetch_fields_error_code_changed");
6363
public static final NodeFeature SPARSE_VECTOR_STORE_SUPPORT = new NodeFeature("mapper.sparse_vector.store_support");
6464
public static final NodeFeature SORT_FIELDS_CHECK_FOR_NESTED_OBJECT_FIX = new NodeFeature("mapper.nested.sorting_fields_check_fix");
65+
public static final NodeFeature DYNAMIC_HANDLING_IN_COPY_TO = new NodeFeature("mapper.copy_to.dynamic_handling");
6566

6667
@Override
6768
public Set<NodeFeature> getTestFeatures() {
@@ -76,8 +77,9 @@ public Set<NodeFeature> getTestFeatures() {
7677
CONSTANT_KEYWORD_SYNTHETIC_SOURCE_WRITE_FIX,
7778
META_FETCH_FIELDS_ERROR_CODE_CHANGED,
7879
SPARSE_VECTOR_STORE_SUPPORT,
79-
SORT_FIELDS_CHECK_FOR_NESTED_OBJECT_FIX,
8080
COUNTED_KEYWORD_SYNTHETIC_SOURCE_NATIVE_SUPPORT,
81+
SORT_FIELDS_CHECK_FOR_NESTED_OBJECT_FIX,
82+
DYNAMIC_HANDLING_IN_COPY_TO,
8183
SourceFieldMapper.SYNTHETIC_RECOVERY_SOURCE,
8284
ObjectMapper.SUBOBJECTS_FALSE_MAPPING_UPDATE_FIX
8385
);

test/framework/src/main/java/org/elasticsearch/logsdb/datageneration/datasource/DefaultMappingParametersHandler.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
import org.elasticsearch.index.mapper.Mapper;
1313
import org.elasticsearch.index.mapper.ObjectMapper;
14-
import org.elasticsearch.logsdb.datageneration.fields.DynamicMapping;
1514
import org.elasticsearch.test.ESTestCase;
1615

1716
import java.util.HashMap;
@@ -50,11 +49,7 @@ private Supplier<Map<String, Object>> keywordMapping(
5049
// We only add copy_to to keywords because we get into trouble with numeric fields that are copied to dynamic fields.
5150
// If first copied value is numeric, dynamic field is created with numeric field type and then copy of text values fail.
5251
// Actual value being copied does not influence the core logic of copy_to anyway.
53-
//
54-
// TODO
55-
// We don't use copy_to on fields that are inside an object with dynamic: strict
56-
// because we'll hit https://github.com/elastic/elasticsearch/issues/113049.
57-
if (request.dynamicMapping() != DynamicMapping.FORBIDDEN && ESTestCase.randomDouble() <= 0.05) {
52+
if (ESTestCase.randomDouble() <= 0.05) {
5853
var options = request.eligibleCopyToFields()
5954
.stream()
6055
.filter(f -> f.equals(request.fieldName()) == false)

0 commit comments

Comments
 (0)