Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -822,7 +822,7 @@ private static class NoOpObjectMapper extends ObjectMapper {
}

@Override
public ObjectMapper merge(Mapper mergeWith, MapperBuilderContext mapperBuilderContext) {
public ObjectMapper merge(Mapper mergeWith, MapperMergeContext mapperMergeContext) {
return this;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public String path() {
}

@Override
public Mapper merge(Mapper mergeWith, MapperBuilderContext mapperBuilderContext) {
public Mapper merge(Mapper mergeWith, MapperMergeContext mapperMergeContext) {
if ((mergeWith instanceof FieldAliasMapper) == false) {
throw new IllegalArgumentException(
"Cannot merge a field alias mapping [" + name() + "] with a mapping that is not for a field alias."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ private static void checkNestedScopeCompatibility(String source, String target)
public abstract Builder getMergeBuilder();

@Override
public final FieldMapper merge(Mapper mergeWith, MapperBuilderContext mapperBuilderContext) {
public final FieldMapper merge(Mapper mergeWith, MapperMergeContext mapperMergeContext) {
if (mergeWith == this) {
return this;
}
Expand All @@ -394,9 +394,9 @@ public final FieldMapper merge(Mapper mergeWith, MapperBuilderContext mapperBuil
return (FieldMapper) mergeWith;
}
Conflicts conflicts = new Conflicts(name());
builder.merge((FieldMapper) mergeWith, conflicts, mapperBuilderContext);
builder.merge((FieldMapper) mergeWith, conflicts, mapperMergeContext);
conflicts.check();
return builder.build(mapperBuilderContext);
return builder.build(mapperMergeContext.getMapperBuilderContext());
}

protected void checkIncomingMergeType(FieldMapper mergeWith) {
Expand Down Expand Up @@ -454,11 +454,11 @@ public Builder add(FieldMapper mapper) {
return this;
}

public Builder update(FieldMapper toMerge, MapperBuilderContext context) {
public Builder update(FieldMapper toMerge, MapperMergeContext context) {
if (mapperBuilders.containsKey(toMerge.simpleName()) == false) {
add(toMerge);
} else {
FieldMapper existing = mapperBuilders.get(toMerge.simpleName()).apply(context);
FieldMapper existing = mapperBuilders.get(toMerge.simpleName()).apply(context.getMapperBuilderContext());
add(existing.merge(toMerge, context));
}
return this;
Expand Down Expand Up @@ -1220,11 +1220,11 @@ public Builder init(FieldMapper initializer) {
return this;
}

protected void merge(FieldMapper in, Conflicts conflicts, MapperBuilderContext mapperBuilderContext) {
protected void merge(FieldMapper in, Conflicts conflicts, MapperMergeContext mapperMergeContext) {
for (Parameter<?> param : getParameters()) {
param.merge(in, conflicts);
}
MapperBuilderContext childContext = mapperBuilderContext.createChildContext(in.simpleName());
MapperMergeContext childContext = mapperMergeContext.createChildContext(in.simpleName());
for (FieldMapper newSubField : in.multiFields.mappers) {
multiFieldsBuilder.update(newSubField, childContext);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,11 @@ public final String simpleName() {
*/
public abstract String typeName();

/** Return the merge of {@code mergeWith} into this.
* Both {@code this} and {@code mergeWith} will be left unmodified. */
public abstract Mapper merge(Mapper mergeWith, MapperBuilderContext mapperBuilderContext);
/**
* Return the merge of {@code mergeWith} into this.
* Both {@code this} and {@code mergeWith} will be left unmodified.
*/
public abstract Mapper merge(Mapper mergeWith, MapperMergeContext mapperMergeContext);

/**
* Validate any cross-field references made by this mapper
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

package org.elasticsearch.index.mapper;

/**
* Holds context used when merging mappings.
* As the merge process also involves building merged {@link Mapper.Builder}s,
* this also contains a {@link MapperBuilderContext}.
*/
public final class MapperMergeContext {

private final MapperBuilderContext mapperBuilderContext;

/**
* The root context, to be used when merging a tree of mappers
*/
public static MapperMergeContext root(boolean isSourceSynthetic, boolean isDataStream) {
return new MapperMergeContext(MapperBuilderContext.root(isSourceSynthetic, isDataStream));
}

/**
* Creates a new {@link MapperMergeContext} from a {@link MapperBuilderContext}
* @param mapperBuilderContext the {@link MapperBuilderContext} for this {@link MapperMergeContext}
* @return a new {@link MapperMergeContext}, wrapping the provided {@link MapperBuilderContext}
*/
public static MapperMergeContext from(MapperBuilderContext mapperBuilderContext) {
return new MapperMergeContext(mapperBuilderContext);
}

private MapperMergeContext(MapperBuilderContext mapperBuilderContext) {
this.mapperBuilderContext = mapperBuilderContext;
}

/**
* Creates a new {@link MapperMergeContext} that is a child of this context
* @param name the name of the child context
* @return a new {@link MapperMergeContext} with this context as its parent
*/
public MapperMergeContext createChildContext(String name) {
return new MapperMergeContext(mapperBuilderContext.createChildContext(name));
}

MapperBuilderContext getMapperBuilderContext() {
return mapperBuilderContext;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public SourceLoader.SyntheticFieldLoader syntheticFieldLoader() {
* @return the resulting merged mapping.
*/
Mapping merge(Mapping mergeWith, MergeReason reason) {
RootObjectMapper mergedRoot = root.merge(mergeWith.root, reason, MapperBuilderContext.root(isSourceSynthetic(), false));
RootObjectMapper mergedRoot = root.merge(mergeWith.root, reason, MapperMergeContext.root(isSourceSynthetic(), false));

// When merging metadata fields as part of applying an index template, new field definitions
// completely overwrite existing ones instead of being merged. This behavior matches how we
Expand All @@ -148,7 +148,7 @@ Mapping merge(Mapping mergeWith, MergeReason reason) {
if (mergeInto == null || reason == MergeReason.INDEX_TEMPLATE) {
merged = metaMergeWith;
} else {
merged = (MetadataFieldMapper) mergeInto.merge(metaMergeWith, MapperBuilderContext.root(isSourceSynthetic(), false));
merged = (MetadataFieldMapper) mergeInto.merge(metaMergeWith, MapperMergeContext.root(isSourceSynthetic(), false));
}
mergedMetadataMappers.put(merged.getClass(), merged);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,12 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
}

@Override
public ObjectMapper merge(Mapper mergeWith, MapperService.MergeReason reason, MapperBuilderContext parentBuilderContext) {
public ObjectMapper merge(Mapper mergeWith, MapperService.MergeReason reason, MapperMergeContext parentMergeContext) {
if ((mergeWith instanceof NestedObjectMapper) == false) {
MapperErrors.throwNestedMappingConflictError(mergeWith.name());
}
NestedObjectMapper mergeWithObject = (NestedObjectMapper) mergeWith;
var mergeResult = MergeResult.build(this, mergeWith, reason, parentBuilderContext);
var mergeResult = MergeResult.build(this, mergeWith, reason, parentMergeContext);
Explicit<Boolean> incInParent = this.includeInParent;
Explicit<Boolean> incInRoot = this.includeInRoot;
if (reason == MapperService.MergeReason.INDEX_TEMPLATE) {
Expand All @@ -230,6 +230,7 @@ public ObjectMapper merge(Mapper mergeWith, MapperService.MergeReason reason, Ma
throw new MapperException("the [include_in_root] parameter can't be updated on a nested object mapping");
}
}
MapperBuilderContext parentBuilderContext = parentMergeContext.getMapperBuilderContext();
if (parentBuilderContext instanceof NestedMapperBuilderContext nc) {
if (nc.parentIncludedInRoot && incInParent.value()) {
incInRoot = Explicit.IMPLICIT_FALSE;
Expand All @@ -253,12 +254,13 @@ public ObjectMapper merge(Mapper mergeWith, MapperService.MergeReason reason, Ma
}

@Override
protected MapperBuilderContext createChildContext(MapperBuilderContext mapperBuilderContext, String name) {
protected MapperMergeContext createChildContext(MapperMergeContext mapperMergeContext, String name) {
MapperBuilderContext mapperBuilderContext = mapperMergeContext.getMapperBuilderContext();
boolean parentIncludedInRoot = this.includeInRoot.value();
if (mapperBuilderContext instanceof NestedMapperBuilderContext == false) {
parentIncludedInRoot |= this.includeInParent.value();
}
return new NestedMapperBuilderContext(mapperBuilderContext.buildFullName(name), parentIncludedInRoot);
return MapperMergeContext.from(new NestedMapperBuilderContext(mapperBuilderContext.buildFullName(name), parentIncludedInRoot));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ protected final Map<String, Mapper> buildMappers(MapperBuilderContext mapperBuil
// This can also happen due to multiple index templates being merged into a single mappings definition using
// XContentHelper#mergeDefaults, again in case some index templates contained mappings for the same field using a
// mix of object notation and dot notation.
mapper = existing.merge(mapper, mapperBuilderContext);
mapper = existing.merge(mapper, MapperMergeContext.from(mapperBuilderContext));
}
mappers.put(mapper.simpleName(), mapper);
}
Expand Down Expand Up @@ -443,8 +443,8 @@ public final boolean subobjects() {
}

@Override
public ObjectMapper merge(Mapper mergeWith, MapperBuilderContext mapperBuilderContext) {
return merge(mergeWith, MergeReason.MAPPING_UPDATE, mapperBuilderContext);
public ObjectMapper merge(Mapper mergeWith, MapperMergeContext mapperMergeContext) {
return merge(mergeWith, MergeReason.MAPPING_UPDATE, mapperMergeContext);
}

@Override
Expand All @@ -454,12 +454,12 @@ public void validate(MappingLookup mappers) {
}
}

protected MapperBuilderContext createChildContext(MapperBuilderContext mapperBuilderContext, String name) {
return mapperBuilderContext.createChildContext(name);
protected MapperMergeContext createChildContext(MapperMergeContext mapperMergeContext, String name) {
return mapperMergeContext.createChildContext(name);
}

public ObjectMapper merge(Mapper mergeWith, MergeReason reason, MapperBuilderContext parentBuilderContext) {
var mergeResult = MergeResult.build(this, mergeWith, reason, parentBuilderContext);
public ObjectMapper merge(Mapper mergeWith, MergeReason reason, MapperMergeContext parentMergeContext) {
var mergeResult = MergeResult.build(this, mergeWith, reason, parentMergeContext);
return new ObjectMapper(
simpleName(),
fullPath,
Expand All @@ -481,7 +481,7 @@ public static MergeResult build(
ObjectMapper existing,
Mapper mergeWith,
MergeReason reason,
MapperBuilderContext parentBuilderContext
MapperMergeContext parentMergeContext
Comment thread
javanna marked this conversation as resolved.
) {
if ((mergeWith instanceof ObjectMapper) == false) {
MapperErrors.throwObjectMappingConflictError(mergeWith.name());
Expand Down Expand Up @@ -517,8 +517,8 @@ public static MergeResult build(
} else {
subObjects = existing.subobjects;
}
MapperBuilderContext objectBuilderContext = existing.createChildContext(parentBuilderContext, existing.simpleName());
Map<String, Mapper> mergedMappers = buildMergedMappers(existing, mergeWith, reason, objectBuilderContext);
MapperMergeContext objectMergeContext = existing.createChildContext(parentMergeContext, existing.simpleName());
Map<String, Mapper> mergedMappers = buildMergedMappers(existing, mergeWith, reason, objectMergeContext);
return new MergeResult(
enabled,
subObjects,
Expand All @@ -531,7 +531,7 @@ private static Map<String, Mapper> buildMergedMappers(
ObjectMapper existing,
Mapper mergeWith,
MergeReason reason,
MapperBuilderContext objectBuilderContext
MapperMergeContext objectMergeContext
) {
Map<String, Mapper> mergedMappers = null;
for (Mapper mergeWithMapper : mergeWith) {
Expand All @@ -541,7 +541,7 @@ private static Map<String, Mapper> buildMergedMappers(
if (mergeIntoMapper == null) {
merged = mergeWithMapper;
} else if (mergeIntoMapper instanceof ObjectMapper objectMapper) {
merged = objectMapper.merge(mergeWithMapper, reason, objectBuilderContext);
merged = objectMapper.merge(mergeWithMapper, reason, objectMergeContext);
} else {
assert mergeIntoMapper instanceof FieldMapper || mergeIntoMapper instanceof FieldAliasMapper;
if (mergeWithMapper instanceof NestedObjectMapper) {
Expand All @@ -555,7 +555,7 @@ private static Map<String, Mapper> buildMergedMappers(
if (reason == MergeReason.INDEX_TEMPLATE) {
merged = mergeWithMapper;
} else {
merged = mergeIntoMapper.merge(mergeWithMapper, objectBuilderContext);
merged = mergeIntoMapper.merge(mergeWithMapper, objectMergeContext);
}
}
if (mergedMappers == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ public FieldMapper.Builder init(FieldMapper initializer) {
}

@Override
protected void merge(FieldMapper in, Conflicts conflicts, MapperBuilderContext mapperBuilderContext) {
protected void merge(FieldMapper in, Conflicts conflicts, MapperMergeContext mapperMergeContext) {
assert in instanceof PlaceHolderFieldMapper;
unknownParams.putAll(((PlaceHolderFieldMapper) in).unknownParams);
super.merge(in, conflicts, mapperBuilderContext);
super.merge(in, conflicts, mapperMergeContext);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,14 @@ RuntimeField getRuntimeField(String name) {
}

@Override
protected MapperBuilderContext createChildContext(MapperBuilderContext mapperBuilderContext, String name) {
assert Objects.equals(mapperBuilderContext.buildFullName("foo"), "foo");
return mapperBuilderContext;
protected MapperMergeContext createChildContext(MapperMergeContext mapperMergeContext, String name) {
assert Objects.equals(mapperMergeContext.getMapperBuilderContext().buildFullName("foo"), "foo");
return mapperMergeContext;
}

@Override
public RootObjectMapper merge(Mapper mergeWith, MergeReason reason, MapperBuilderContext parentBuilderContext) {
final var mergeResult = MergeResult.build(this, mergeWith, reason, parentBuilderContext);
public RootObjectMapper merge(Mapper mergeWith, MergeReason reason, MapperMergeContext parentMergeContext) {
final var mergeResult = MergeResult.build(this, mergeWith, reason, parentMergeContext);
final Explicit<Boolean> numericDetection;
RootObjectMapper mergeWithObject = (RootObjectMapper) mergeWith;
if (mergeWithObject.numericDetection.explicit()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1508,14 +1508,14 @@ public void testMergeNested() {

MapperException e = expectThrows(
MapperException.class,
() -> firstMapper.merge(secondMapper, MapperBuilderContext.root(false, false))
() -> firstMapper.merge(secondMapper, MapperMergeContext.root(false, false))
);
assertThat(e.getMessage(), containsString("[include_in_parent] parameter can't be updated on a nested object mapping"));

NestedObjectMapper result = (NestedObjectMapper) firstMapper.merge(
secondMapper,
MapperService.MergeReason.INDEX_TEMPLATE,
MapperBuilderContext.root(false, false)
MapperMergeContext.root(false, false)
);
assertFalse(result.isIncludeInParent());
assertTrue(result.isIncludeInRoot());
Expand Down
Loading