From 704524d7f48a18d72cdaed4e09c3baeffd659805 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Tue, 16 Jan 2018 10:06:38 +0100 Subject: [PATCH] DATAMONGO-1843 - Fix parameter shadowing in ArrayOperators reduce. Original pull request: #526. --- .../core/aggregation/ArrayOperators.java | 14 +++++------ .../ProjectionOperationUnitTests.java | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java index 2c3ace86c..95d4b4a91 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/aggregation/ArrayOperators.java @@ -229,8 +229,8 @@ public class ArrayOperators { @Override public Reduce startingWith(Object initialValue) { - return (usesFieldRef() ? Reduce.arrayOf(fieldReference) : Reduce.arrayOf(expression)) - .withInitialValue(initialValue).reduce(expression); + return (usesFieldRef() ? Reduce.arrayOf(fieldReference) + : Reduce.arrayOf(ArrayOperatorFactory.this.expression)).withInitialValue(initialValue).reduce(expression); } }; } @@ -1104,12 +1104,10 @@ public class ArrayOperators { /** * Start creating new {@link Reduce}. * - * @param expression must not be {@literal null}. + * @param arrayValueExpression must not be {@literal null}. * @return */ - public static InitialValueBuilder arrayOf(final AggregationExpression expression) { - - Assert.notNull(expression, "AggregationExpression must not be null"); + public static InitialValueBuilder arrayOf(final AggregationExpression arrayValueExpression) { return new InitialValueBuilder() { @@ -1124,14 +1122,14 @@ public class ArrayOperators { public Reduce reduce(AggregationExpression expression) { Assert.notNull(expression, "AggregationExpression must not be null"); - return new Reduce(expression, initialValue, Collections.singletonList(expression)); + return new Reduce(arrayValueExpression, initialValue, Collections.singletonList(expression)); } @Override public Reduce reduce(PropertyExpression... expressions) { Assert.notNull(expressions, "PropertyExpressions must not be null"); - return new Reduce(expression, initialValue, Arrays. asList(expressions)); + return new Reduce(arrayValueExpression, initialValue, Arrays.asList(expressions)); } }; } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java index 575c91672..5bc37e7d4 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/aggregation/ProjectionOperationUnitTests.java @@ -32,10 +32,13 @@ import org.hamcrest.Matchers; import org.junit.Test; import org.springframework.data.domain.Range; import org.springframework.data.mongodb.core.DocumentTestUtils; +import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce; import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce.PropertyExpression; import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Reduce.Variable; +import org.springframework.data.mongodb.core.aggregation.ArrayOperators.Slice; import org.springframework.data.mongodb.core.aggregation.ConditionalOperators.Switch.CaseOperator; import org.springframework.data.mongodb.core.aggregation.ProjectionOperation.ProjectionOperationBuilder; +import org.springframework.data.mongodb.core.aggregation.StringOperators.Concat; import org.springframework.data.mongodb.core.aggregation.VariableOperators.Let.ExpressionVariable; /** @@ -1573,6 +1576,27 @@ public class ProjectionOperationUnitTests { "{ $project : { \"results\": { $reduce: { input: \"$probabilityArr\", initialValue: { \"sum\" : 5 , \"product\" : 2} , in: { \"sum\": { $add : [\"$$value.sum\", \"$$this\"] }, \"product\": { $multiply: [ \"$$value.product\", \"$$this\" ] } } } } } }"))); } + @Test // DATAMONGO-1843 + public void shouldRenderReduceWithInputAndInExpressionsCorrectly() { + + Document exprected = Document.parse( + "{ \"$project\" : { \"results\" : { \"$reduce\" : { \"input\" : { \"$slice\" : [\"$array\", 5] }, \"initialValue\" : \"\", \"in\" : { \"$concat\" : [\"$$value\", \"/\", \"$$this\"] } } } } }"); + + Reduce reduceEntryPoint = Reduce.arrayOf(Slice.sliceArrayOf("array").itemCount(5)) // + .withInitialValue("") // + .reduce(Concat.valueOf("$$value").concat("/").concatValueOf("$$this")); + + Reduce arrayEntryPoint = ArrayOperators.arrayOf(Slice.sliceArrayOf("array").itemCount(5)) // + .reduce(Concat.valueOf("$$value").concat("/").concatValueOf("$$this")) // + .startingWith(""); + + assertThat(project().and(reduceEntryPoint).as("results").toDocument(Aggregation.DEFAULT_CONTEXT), + Matchers.is(exprected)); + + assertThat(project().and(arrayEntryPoint).as("results").toDocument(Aggregation.DEFAULT_CONTEXT), + Matchers.is(exprected)); + } + @Test // DATAMONGO-1548 public void shouldRenderZipCorrectly() {