Skip to content

Commit 1225b07

Browse files
authored
Fix propagation of dynamic mapping parameter when applying copy_to (#121109)
1 parent 1c1f195 commit 1225b07

File tree

6 files changed

+60
-7
lines changed

6 files changed

+60
-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

rest-api-spec/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,5 @@ tasks.named("yamlRestCompatTestTransform").configure ({ task ->
7373
task.skipTest("index/92_metrics_auto_subobjects/Root without subobjects with synthetic source", "_source.mode mapping attribute is no-op since 9.0.0")
7474
task.skipTest("index/91_metrics_no_subobjects/Metrics object indexing with synthetic source", "_source.mode mapping attribute is no-op since 9.0.0")
7575
task.skipTest("index/91_metrics_no_subobjects/Root without subobjects with synthetic source", "_source.mode mapping attribute is no-op since 9.0.0")
76+
task.skipTest("indices.create/20_synthetic_source/synthetic_source with copy_to inside nested object", "temporary until backported")
7677
})
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
@@ -30,6 +30,7 @@ public class MapperFeatures implements FeatureSpecification {
3030
public static final NodeFeature META_FETCH_FIELDS_ERROR_CODE_CHANGED = new NodeFeature("meta_fetch_fields_error_code_changed");
3131
public static final NodeFeature SPARSE_VECTOR_STORE_SUPPORT = new NodeFeature("mapper.sparse_vector.store_support");
3232
public static final NodeFeature SORT_FIELDS_CHECK_FOR_NESTED_OBJECT_FIX = new NodeFeature("mapper.nested.sorting_fields_check_fix");
33+
public static final NodeFeature DYNAMIC_HANDLING_IN_COPY_TO = new NodeFeature("mapper.copy_to.dynamic_handling");
3334

3435
@Override
3536
public Set<NodeFeature> getTestFeatures() {
@@ -45,8 +46,9 @@ public Set<NodeFeature> getTestFeatures() {
4546
CONSTANT_KEYWORD_SYNTHETIC_SOURCE_WRITE_FIX,
4647
META_FETCH_FIELDS_ERROR_CODE_CHANGED,
4748
SPARSE_VECTOR_STORE_SUPPORT,
48-
SORT_FIELDS_CHECK_FOR_NESTED_OBJECT_FIX,
4949
COUNTED_KEYWORD_SYNTHETIC_SOURCE_NATIVE_SUPPORT,
50+
SORT_FIELDS_CHECK_FOR_NESTED_OBJECT_FIX,
51+
DYNAMIC_HANDLING_IN_COPY_TO,
5052
SourceFieldMapper.SYNTHETIC_RECOVERY_SOURCE,
5153
ObjectMapper.SUBOBJECTS_FALSE_MAPPING_UPDATE_FIX
5254
);

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)