Skip to content

Commit 733e695

Browse files
committed
Merge branch '6.2.x'
2 parents e673345 + b98c325 commit 733e695

File tree

1 file changed

+101
-58
lines changed

1 file changed

+101
-58
lines changed

spring-r2dbc/src/test/java/org/springframework/r2dbc/core/NamedParameterUtilsTests.java

+101-58
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,13 +16,12 @@
1616

1717
package org.springframework.r2dbc.core;
1818

19-
import java.util.Arrays;
20-
import java.util.Collections;
2119
import java.util.HashMap;
22-
import java.util.LinkedHashMap;
20+
import java.util.List;
2321
import java.util.Map;
2422

2523
import io.r2dbc.spi.Parameters;
24+
import org.junit.jupiter.api.Disabled;
2625
import org.junit.jupiter.api.Test;
2726
import org.junit.jupiter.params.ParameterizedTest;
2827
import org.junit.jupiter.params.provider.ValueSource;
@@ -42,10 +41,13 @@
4241
* @author Mark Paluch
4342
* @author Jens Schauder
4443
* @author Anton Naydenov
44+
* @author Sam Brannen
4545
*/
4646
class NamedParameterUtilsTests {
4747

48-
private final BindMarkersFactory BIND_MARKERS = BindMarkersFactory.indexed("$", 1);
48+
private static final BindMarkersFactory INDEXED_MARKERS = BindMarkersFactory.indexed("$", 1);
49+
50+
private static final BindMarkersFactory ANONYMOUS_MARKERS = BindMarkersFactory.anonymous("?");
4951

5052

5153
@Test
@@ -73,7 +75,7 @@ void substituteNamedParameters() {
7375
namedParams.addValue("a", "a").addValue("b", "b").addValue("c", "c");
7476

7577
PreparedOperation<?> operation = NamedParameterUtils.substituteNamedParameters(
76-
"xxx :a :b :c", BIND_MARKERS, namedParams);
78+
"xxx :a :b :c", INDEXED_MARKERS, namedParams);
7779

7880
assertThat(operation.toQuery()).isEqualTo("xxx $1 $2 $3");
7981

@@ -87,11 +89,11 @@ void substituteNamedParameters() {
8789
void substituteObjectArray() {
8890
MapBindParameterSource namedParams = new MapBindParameterSource(new HashMap<>());
8991
namedParams.addValue("a",
90-
Arrays.asList(new Object[] {"Walter", "Heisenberg"},
91-
new Object[] {"Walt Jr.", "Flynn"}));
92+
List.of(new Object[] {"Walter", "Heisenberg"},
93+
new Object[] {"Walt Jr.", "Flynn"}));
9294

9395
PreparedOperation<?> operation = NamedParameterUtils.substituteNamedParameters(
94-
"xxx :a", BIND_MARKERS, namedParams);
96+
"xxx :a", INDEXED_MARKERS, namedParams);
9597

9698
assertThat(operation.toQuery()).isEqualTo("xxx ($1, $2), ($3, $4)");
9799
}
@@ -100,13 +102,13 @@ void substituteObjectArray() {
100102
void shouldBindObjectArray() {
101103
MapBindParameterSource namedParams = new MapBindParameterSource(new HashMap<>());
102104
namedParams.addValue("a",
103-
Arrays.asList(new Object[] {"Walter", "Heisenberg"},
104-
new Object[] {"Walt Jr.", "Flynn"}));
105+
List.of(new Object[] {"Walter", "Heisenberg"},
106+
new Object[] {"Walt Jr.", "Flynn"}));
105107

106108
BindTarget bindTarget = mock();
107109

108110
PreparedOperation<?> operation = NamedParameterUtils.substituteNamedParameters(
109-
"xxx :a", BIND_MARKERS, namedParams);
111+
"xxx :a", INDEXED_MARKERS, namedParams);
110112
operation.bindTo(bindTarget);
111113

112114
verify(bindTarget).bind(0, "Walter");
@@ -141,7 +143,7 @@ void parseSqlStatementWithPostgresCasting() {
141143

142144
ParsedSql parsedSql = NamedParameterUtils.parseSqlStatement(sql);
143145
PreparedOperation<?> operation = NamedParameterUtils.substituteNamedParameters(
144-
parsedSql, BIND_MARKERS, new MapBindParameterSource());
146+
parsedSql, INDEXED_MARKERS, new MapBindParameterSource());
145147

146148
assertThat(operation.toQuery()).isEqualTo(expectedSql);
147149
}
@@ -312,14 +314,13 @@ void shouldAllowParsingMultipleUseOfParameter() {
312314
void multipleEqualParameterReferencesBindsValueOnce() {
313315
String sql = "SELECT * FROM person where name = :id or lastname = :id";
314316

315-
BindMarkersFactory factory = BindMarkersFactory.indexed("$", 0);
317+
MapBindParameterSource source = new MapBindParameterSource(Map.of("id", Parameters.in("foo")));
318+
PreparedOperation<String> operation = NamedParameterUtils.substituteNamedParameters(sql, INDEXED_MARKERS, source);
316319

317-
PreparedOperation<String> operation = NamedParameterUtils.substituteNamedParameters(
318-
sql, factory, new MapBindParameterSource(
319-
Collections.singletonMap("id", Parameters.in("foo"))));
320+
assertThat(operation.toQuery())
321+
.isEqualTo("SELECT * FROM person where name = $1 or lastname = $1");
320322

321-
assertThat(operation.toQuery()).isEqualTo(
322-
"SELECT * FROM person where name = $0 or lastname = $0");
323+
Map<Integer, Object> bindings = new HashMap<>();
323324

324325
operation.bindTo(new BindTarget() {
325326
@Override
@@ -328,8 +329,7 @@ public void bind(String identifier, Object value) {
328329
}
329330
@Override
330331
public void bind(int index, Object value) {
331-
assertThat(index).isEqualTo(0);
332-
assertThat(value).isEqualTo(Parameters.in("foo"));
332+
bindings.put(index, value);
333333
}
334334
@Override
335335
public void bindNull(String identifier, Class<?> type) {
@@ -340,22 +340,24 @@ public void bindNull(int index, Class<?> type) {
340340
throw new UnsupportedOperationException();
341341
}
342342
});
343+
344+
assertThat(bindings)
345+
.hasSize(1)
346+
.containsEntry(0, Parameters.in("foo"));
343347
}
344348

345349
@Test
346-
void multipleEqualCollectionParameterReferencesBindsValueOnce() {
350+
void multipleEqualCollectionParameterReferencesForIndexedMarkersBindsValueOnce() {
347351
String sql = "SELECT * FROM person where name IN (:ids) or lastname IN (:ids)";
348352

349-
BindMarkersFactory factory = BindMarkersFactory.indexed("$", 0);
350-
351-
MultiValueMap<Integer, Object> bindings = new LinkedMultiValueMap<>();
353+
MapBindParameterSource source = new MapBindParameterSource(Map.of("ids",
354+
Parameters.in(List.of("foo", "bar", "baz"))));
355+
PreparedOperation<String> operation = NamedParameterUtils.substituteNamedParameters(sql, INDEXED_MARKERS, source);
352356

353-
PreparedOperation<String> operation = NamedParameterUtils.substituteNamedParameters(
354-
sql, factory, new MapBindParameterSource(Collections.singletonMap("ids",
355-
Parameters.in(Arrays.asList("foo", "bar", "baz")))));
357+
assertThat(operation.toQuery())
358+
.isEqualTo("SELECT * FROM person where name IN ($1, $2, $3) or lastname IN ($1, $2, $3)");
356359

357-
assertThat(operation.toQuery()).isEqualTo(
358-
"SELECT * FROM person where name IN ($0, $1, $2) or lastname IN ($0, $1, $2)");
360+
MultiValueMap<Integer, Object> bindings = new LinkedMultiValueMap<>();
359361

360362
operation.bindTo(new BindTarget() {
361363
@Override
@@ -364,8 +366,6 @@ public void bind(String identifier, Object value) {
364366
}
365367
@Override
366368
public void bind(int index, Object value) {
367-
assertThat(index).isIn(0, 1, 2);
368-
assertThat(value).isIn("foo", "bar", "baz");
369369
bindings.add(index, value);
370370
}
371371
@Override
@@ -378,25 +378,63 @@ public void bindNull(int index, Class<?> type) {
378378
}
379379
});
380380

381-
assertThat(bindings).containsEntry(0, Collections.singletonList("foo")) //
382-
.containsEntry(1, Collections.singletonList("bar")) //
383-
.containsEntry(2, Collections.singletonList("baz"));
381+
assertThat(bindings)
382+
.hasSize(3)
383+
.containsEntry(0, List.of("foo"))
384+
.containsEntry(1, List.of("bar"))
385+
.containsEntry(2, List.of("baz"));
386+
}
387+
388+
@Test // gh-34768
389+
@Disabled("Disabled until gh-34768 is addressed")
390+
void multipleEqualCollectionParameterReferencesForAnonymousMarkersBindsValueTwice() {
391+
String sql = "SELECT * FROM fund_info WHERE fund_code IN (:fundCodes) OR fund_code IN (:fundCodes)";
392+
393+
MapBindParameterSource source = new MapBindParameterSource(Map.of("fundCodes", Parameters.in(List.of("foo"))));
394+
PreparedOperation<String> operation = NamedParameterUtils.substituteNamedParameters(sql, ANONYMOUS_MARKERS, source);
395+
396+
assertThat(operation.toQuery())
397+
.isEqualTo("SELECT * FROM fund_info WHERE fund_code IN (?) OR fund_code IN (?)");
398+
399+
Map<Integer, Object> bindings = new HashMap<>();
400+
401+
operation.bindTo(new BindTarget() {
402+
@Override
403+
public void bind(String identifier, Object value) {}
404+
405+
@Override
406+
public void bind(int index, Object value) {
407+
bindings.put(index, value);
408+
}
409+
410+
@Override
411+
public void bindNull(String identifier, Class<?> type) {
412+
throw new UnsupportedOperationException();
413+
}
414+
415+
@Override
416+
public void bindNull(int index, Class<?> type) {
417+
throw new UnsupportedOperationException();
418+
}
419+
});
420+
421+
assertThat(bindings)
422+
.hasSize(2)
423+
.containsEntry(0, "foo")
424+
.containsEntry(1, "foo");
384425
}
385426

386427
@Test
387-
void multipleEqualParameterReferencesForAnonymousMarkersBindsValueMultipleTimes() {
428+
void multipleEqualParameterReferencesForAnonymousMarkersBindsValueTwice() {
388429
String sql = "SELECT * FROM person where name = :id or lastname = :id";
389430

390-
BindMarkersFactory factory = BindMarkersFactory.anonymous("?");
391-
392-
PreparedOperation<String> operation = NamedParameterUtils.substituteNamedParameters(
393-
sql, factory, new MapBindParameterSource(
394-
Collections.singletonMap("id", Parameters.in("foo"))));
431+
MapBindParameterSource source = new MapBindParameterSource(Map.of("id", Parameters.in("foo")));
432+
PreparedOperation<String> operation = NamedParameterUtils.substituteNamedParameters(sql, ANONYMOUS_MARKERS, source);
395433

396-
assertThat(operation.toQuery()).isEqualTo(
397-
"SELECT * FROM person where name = ? or lastname = ?");
434+
assertThat(operation.toQuery())
435+
.isEqualTo("SELECT * FROM person where name = ? or lastname = ?");
398436

399-
Map<Integer, Object> bindValues = new LinkedHashMap<>();
437+
Map<Integer, Object> bindings = new HashMap<>();
400438

401439
operation.bindTo(new BindTarget() {
402440
@Override
@@ -405,7 +443,7 @@ public void bind(String identifier, Object value) {
405443
}
406444
@Override
407445
public void bind(int index, Object value) {
408-
bindValues.put(index, value);
446+
bindings.put(index, value);
409447
}
410448
@Override
411449
public void bindNull(String identifier, Class<?> type) {
@@ -417,21 +455,23 @@ public void bindNull(int index, Class<?> type) {
417455
}
418456
});
419457

420-
assertThat(bindValues).hasSize(2).containsEntry(0, Parameters.in("foo")).containsEntry(1, Parameters.in("foo"));
458+
assertThat(bindings)
459+
.hasSize(2)
460+
.containsEntry(0, Parameters.in("foo"))
461+
.containsEntry(1, Parameters.in("foo"));
421462
}
422463

423464
@Test
424465
void multipleEqualParameterReferencesBindsNullOnce() {
425466
String sql = "SELECT * FROM person where name = :id or lastname = :id";
426467

427-
BindMarkersFactory factory = BindMarkersFactory.indexed("$", 0);
468+
MapBindParameterSource source = new MapBindParameterSource(Map.of("id", Parameters.in(String.class)));
469+
PreparedOperation<String> operation = NamedParameterUtils.substituteNamedParameters(sql, INDEXED_MARKERS, source);
428470

429-
PreparedOperation<String> operation = NamedParameterUtils.substituteNamedParameters(
430-
sql, factory, new MapBindParameterSource(
431-
Collections.singletonMap("id", Parameters.in(String.class))));
471+
assertThat(operation.toQuery())
472+
.isEqualTo("SELECT * FROM person where name = $1 or lastname = $1");
432473

433-
assertThat(operation.toQuery()).isEqualTo(
434-
"SELECT * FROM person where name = $0 or lastname = $0");
474+
Map<Integer, Object> bindings = new HashMap<>();
435475

436476
operation.bindTo(new BindTarget() {
437477
@Override
@@ -440,8 +480,7 @@ public void bind(String identifier, Object value) {
440480
}
441481
@Override
442482
public void bind(int index, Object value) {
443-
assertThat(index).isEqualTo(0);
444-
assertThat(value).isEqualTo(Parameters.in(String.class));
483+
bindings.put(index, value);
445484
}
446485
@Override
447486
public void bindNull(String identifier, Class<?> type) {
@@ -452,16 +491,20 @@ public void bindNull(int index, Class<?> type) {
452491
throw new UnsupportedOperationException();
453492
}
454493
});
494+
495+
assertThat(bindings)
496+
.hasSize(1)
497+
.containsEntry(0, Parameters.in(String.class));
455498
}
456499

457500

458-
private String expand(ParsedSql sql) {
459-
return NamedParameterUtils.substituteNamedParameters(sql, BIND_MARKERS,
501+
private static String expand(ParsedSql sql) {
502+
return NamedParameterUtils.substituteNamedParameters(sql, INDEXED_MARKERS,
460503
new MapBindParameterSource()).toQuery();
461504
}
462505

463-
private String expand(String sql) {
464-
return NamedParameterUtils.substituteNamedParameters(sql, BIND_MARKERS,
506+
private static String expand(String sql) {
507+
return NamedParameterUtils.substituteNamedParameters(sql, INDEXED_MARKERS,
465508
new MapBindParameterSource()).toQuery();
466509
}
467510

0 commit comments

Comments
 (0)