From dd6eede243b92dbbbc3790516f2a439f2941a8f4 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Fri, 9 May 2025 14:27:19 +0200 Subject: [PATCH] Properly expand reused collection parameters in R2DBC NamedParameterUtils Prior to this commit, NamedParameterUtils in spring-r2dbc did not properly expand reused collection parameters. Specifically, values in a supplied collection were only expanded in the resulting query once, for the first occurrence of the named parameter. To address that, this commit effectively reinstates the original logic for ExpandedQuery from NamedParameterUtils in the Spring Data R2DBC project. https://github.com/spring-projects/spring-data-relational/blob/94958f5eb66cbe2e8e025155cd99abf36f6f91f4/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/core/NamedParameterUtils.java#L486 Closes gh-34768 --- .../r2dbc/core/NamedParameterUtils.java | 49 ++++++++++--------- .../r2dbc/core/NamedParameterUtilsTests.java | 2 - 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java index 630a00b7512..76b7adfcb87 100644 --- a/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java +++ b/spring-r2dbc/src/main/java/org/springframework/r2dbc/core/NamedParameterUtils.java @@ -49,6 +49,7 @@ import org.springframework.util.Assert; * @author Juergen Hoeller * @author Mark Paluch * @author Anton Naydenov + * @author Sam Brannen * @since 5.3 */ abstract class NamedParameterUtils { @@ -545,41 +546,43 @@ abstract class NamedParameterUtils { } private void bindNull(BindTarget target, String identifier, Parameter parameter) { - List bindMarkers = getBindMarkers(identifier); + List> bindMarkers = getBindMarkers(identifier); if (bindMarkers == null) { target.bind(identifier, parameter); return; } - for (BindMarker bindMarker : bindMarkers) { - bindMarker.bind(target, parameter); + for (List outer : bindMarkers) { + for (BindMarker bindMarker : outer) { + bindMarker.bind(target, parameter); + } } } - @SuppressWarnings({"rawtypes", "unchecked"}) private void bind(BindTarget target, String identifier, Parameter parameter) { - List bindMarkers = getBindMarkers(identifier); + List> bindMarkers = getBindMarkers(identifier); if (bindMarkers == null) { target.bind(identifier, parameter); return; } - if (parameter.getValue() instanceof Collection collection) { - Iterator iterator = collection.iterator(); - Iterator markers = bindMarkers.iterator(); - while (iterator.hasNext()) { - Object valueToBind = iterator.next(); - if (valueToBind instanceof Object[] objects) { - for (Object object : objects) { - bind(target, markers, object); + + for (List outer : bindMarkers) { + if (parameter.getValue() instanceof Collection collection) { + Iterator markers = outer.iterator(); + for (Object valueToBind : collection) { + if (valueToBind instanceof Object[] objects) { + for (Object object : objects) { + bind(target, markers, object); + } + } + else { + bind(target, markers, valueToBind); } - } - else { - bind(target, markers, valueToBind); } } - } - else { - for (BindMarker bindMarker : bindMarkers) { - bindMarker.bind(target, parameter); + else { + for (BindMarker bindMarker : outer) { + bindMarker.bind(target, parameter); + } } } } @@ -592,14 +595,14 @@ abstract class NamedParameterUtils { } @Nullable - private List getBindMarkers(String identifier) { + private List> getBindMarkers(String identifier) { List parameters = this.parameters.getMarker(identifier); if (parameters == null) { return null; } - List markers = new ArrayList<>(); + List> markers = new ArrayList<>(); for (NamedParameters.NamedParameter parameter : parameters) { - markers.addAll(parameter.placeholders); + markers.add(new ArrayList<>(parameter.placeholders)); } return markers; } diff --git a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/NamedParameterUtilsTests.java b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/NamedParameterUtilsTests.java index 9cd68ee3998..725bcf72a92 100644 --- a/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/NamedParameterUtilsTests.java +++ b/spring-r2dbc/src/test/java/org/springframework/r2dbc/core/NamedParameterUtilsTests.java @@ -21,7 +21,6 @@ import java.util.List; import java.util.Map; import io.r2dbc.spi.Parameters; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -350,7 +349,6 @@ class NamedParameterUtilsTests { } @Test // gh-34768 - @Disabled("Disabled until gh-34768 is addressed") void multipleEqualCollectionParameterReferencesForAnonymousMarkersBindsValuesTwice() { String sql = "SELECT * FROM fund_info WHERE fund_code IN (:fundCodes) OR fund_code IN (:fundCodes)";