Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a shallow copy method to aggregation builders #28430

Merged
merged 2 commits into from
Feb 1, 2018

Conversation

jimczi
Copy link
Contributor

@jimczi jimczi commented Jan 29, 2018

This change adds a shallow copy method for aggregation builders. This method returns a copy of the builder replacing the factoriesBuilder and metaData.
This method is used when the builder is rewritten (AggregationBuilder#rewrite) in order to make sure that we create a new instance of the parent builder when sub aggregations are rewritten.

Relates #27782

@jimczi
Copy link
Contributor Author

jimczi commented Jan 29, 2018

@colings86 sorry ;), I asked for help because I thought that each builder would need a specific test for the added method but BaseAggregationTestCase can
test it simply so I decided to do it in a single pr. I'll add a specific test for #27782 in a follow up.

@jimczi jimczi requested a review from colings86 January 29, 2018 22:23
Copy link
Contributor

@colings86 colings86 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jimczi I think it mostly looks good, my only comments are around the fields in the clone potentially being mutated and affecting the original which I think we need to protect against.

@@ -52,6 +55,10 @@ protected AggregationBuilder(String name) {
this.name = name;
}

protected AggregationBuilder(AggregationBuilder clone) {
this.name = clone.name;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is supposed to produce and exact clone of the passed in builder then should we not set the factoriesBuilder here too?

protected AbstractRangeBuilder(AbstractRangeBuilder<AB, R> clone) {
super(clone);
this.rangeFactory = clone.rangeFactory;
this.ranges = clone.ranges;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we might want to copy the list here rather than share it between the old and new copies? Otherwise if the builder is cloned and then addRange is called on the copy it will also change the original?

this.distanceType = clone.distanceType;
this.unit = clone.unit;
this.keyed = clone.keyed;
this.ranges = clone.ranges;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should copy the ranges list?

@@ -222,6 +222,17 @@ public IpRangeAggregationBuilder(String name) {
super(name, ValuesSourceType.BYTES, ValueType.IP);
}

protected IpRangeAggregationBuilder(IpRangeAggregationBuilder clone) {
super(clone);
this.ranges = clone.ranges;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should copy the ranges list?

@@ -129,6 +129,20 @@ public SignificantTermsAggregationBuilder(StreamInput in) throws IOException {
significanceHeuristic = in.readNamedWriteable(SignificanceHeuristic.class);
}

protected SignificantTermsAggregationBuilder(SignificantTermsAggregationBuilder clone) {
super(clone);
this.bucketCountThresholds = clone.bucketCountThresholds;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that BucketCountThresholds is mutable so I think we need to clone it as well?

@@ -123,6 +123,22 @@ public AggregationBuilder parse(String aggregationName, XContentParser parser)
};
}

protected SignificantTextAggregationBuilder(SignificantTextAggregationBuilder clone) {
super(clone);
this.bucketCountThresholds = clone.bucketCountThresholds;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that BucketCountThresholds is mutable so I think we need to clone it as well?

super(clone);
this.bucketCountThresholds = clone.bucketCountThresholds;
this.fieldName = clone.fieldName;
this.filterBuilder = clone.filterBuilder;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this filterBuilder potentially mutable too?

this.executionHint = clone.executionHint;
this.includeExclude = clone.includeExclude;
this.collectMode = clone.collectMode;
this.bucketCountThresholds = clone.bucketCountThresholds;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that BucketCountThresholds is mutable so I think we need to clone it as well?

this.storedFieldsContext = clone.storedFieldsContext;
this.fieldDataFields = clone.fieldDataFields;
this.scriptFields = clone.scriptFields;
this.fetchSourceContext = clone.fetchSourceContext;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are any of these object mutable?

@jimczi jimczi changed the title Add a clone method to all aggregation builders Add a shallow copy method to aggregation builders Jan 31, 2018
@jimczi
Copy link
Contributor Author

jimczi commented Jan 31, 2018

Thanks for reviewing @colings86 .
I pushed a commit after yesterday's discussion that changes the method name (shallowCopy) and ensures that we also recreate mutable objects in the builders.
Can you take another look ?

Copy link
Contributor

@colings86 colings86 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for making the changes

This change adds a shallow copy method for aggregation builders. This method returns a copy of the builder replacing the factoriesBuilder and metaDada
This method is used when the builder is rewritten (AggregationBuilder#rewrite) in order to make sure that
we create a new instance of the parent builder when sub aggregations are rewritten.

Relates elastic#27782
@jimczi jimczi merged commit dd40b98 into elastic:master Feb 1, 2018
@jimczi jimczi deleted the bugs/agg_builder_clone branch February 1, 2018 08:22
jimczi added a commit that referenced this pull request Feb 1, 2018
This change adds a shallow copy method for aggregation builders. This method returns a copy of the builder replacing the factoriesBuilder and metaDada
This method is used when the builder is rewritten (AggregationBuilder#rewrite) in order to make sure that we create a new instance of the parent builder when sub aggregations are rewritten.

Relates #27782
jimczi added a commit to jimczi/elasticsearch that referenced this pull request Feb 2, 2018
This commit adds a test to check that the rewrite of a sub-aggregation triggers a copy of the parent aggregation.

Relates elastic#28430
Closes elastic#27782
jimczi added a commit that referenced this pull request Feb 2, 2018
This commit adds a test to check that the rewrite of a sub-aggregation triggers a copy of the parent aggregation.

Relates #28430
Closes #27782
jimczi added a commit that referenced this pull request Feb 2, 2018
This commit adds a test to check that the rewrite of a sub-aggregation triggers a copy of the parent aggregation.

Relates #28430
Closes #27782
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants