Browse Source

Reject iterable/collection value for positional parameter

Closes gh-31215
pull/31226/head
Juergen Hoeller 2 years ago
parent
commit
ae8a353041
  1. 10
      spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/DefaultJdbcClient.java
  2. 123
      spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/JdbcClientQueryTests.java

10
spring-jdbc/src/main/java/org/springframework/jdbc/core/simple/DefaultJdbcClient.java

@ -106,6 +106,7 @@ final class DefaultJdbcClient implements JdbcClient { @@ -106,6 +106,7 @@ final class DefaultJdbcClient implements JdbcClient {
@Override
public StatementSpec param(@Nullable Object value) {
validateIndexedParamValue(value);
this.indexedParams.add(value);
return this;
}
@ -115,6 +116,7 @@ final class DefaultJdbcClient implements JdbcClient { @@ -115,6 +116,7 @@ final class DefaultJdbcClient implements JdbcClient {
if (jdbcIndex < 1) {
throw new IllegalArgumentException("Invalid JDBC index: needs to start at 1");
}
validateIndexedParamValue(value);
int index = jdbcIndex - 1;
int size = this.indexedParams.size();
if (index < size) {
@ -129,6 +131,14 @@ final class DefaultJdbcClient implements JdbcClient { @@ -129,6 +131,14 @@ final class DefaultJdbcClient implements JdbcClient {
return this;
}
private void validateIndexedParamValue(@Nullable Object value) {
if (value instanceof Iterable) {
throw new IllegalArgumentException("Invalid positional parameter value of type Iterable (" +
value.getClass().getSimpleName() +
"): Parameter expansion is only supported with named parameters.");
}
}
@Override
public StatementSpec param(int jdbcIndex, @Nullable Object value, int sqlType) {
return param(jdbcIndex, new SqlParameterValue(sqlType, value));

123
spring-jdbc/src/test/java/org/springframework/jdbc/core/simple/JdbcClientQueryTests.java

@ -30,11 +30,11 @@ import java.util.Optional; @@ -30,11 +30,11 @@ import java.util.Optional;
import javax.sql.DataSource;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
@ -46,10 +46,10 @@ import static org.mockito.Mockito.verify; @@ -46,10 +46,10 @@ import static org.mockito.Mockito.verify;
*/
public class JdbcClientQueryTests {
private Connection connection = mock();
private DataSource dataSource = mock();
private Connection connection = mock();
private PreparedStatement preparedStatement = mock();
private ResultSet resultSet = mock();
@ -62,17 +62,10 @@ public class JdbcClientQueryTests { @@ -62,17 +62,10 @@ public class JdbcClientQueryTests {
@BeforeEach
public void setup() throws Exception {
given(dataSource.getConnection()).willReturn(connection);
given(resultSetMetaData.getColumnCount()).willReturn(1);
given(resultSetMetaData.getColumnLabel(1)).willReturn("age");
given(connection.prepareStatement(anyString())).willReturn(preparedStatement);
given(preparedStatement.executeQuery()).willReturn(resultSet);
}
@AfterEach
public void verifyClose() throws Exception {
verify(preparedStatement).close();
verify(resultSet).close();
verify(connection).close();
given(resultSetMetaData.getColumnCount()).willReturn(1);
given(resultSetMetaData.getColumnLabel(1)).willReturn("age");
}
@ -93,6 +86,9 @@ public class JdbcClientQueryTests { @@ -93,6 +86,9 @@ public class JdbcClientQueryTests {
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -105,6 +101,9 @@ public class JdbcClientQueryTests { @@ -105,6 +101,9 @@ public class JdbcClientQueryTests {
assertThat(li.size()).as("All rows returned").isEqualTo(0);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -120,6 +119,9 @@ public class JdbcClientQueryTests { @@ -120,6 +119,9 @@ public class JdbcClientQueryTests {
assertThat(li.get(0).get("age")).as("First row is Integer").isEqualTo(11);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -136,6 +138,9 @@ public class JdbcClientQueryTests { @@ -136,6 +138,9 @@ public class JdbcClientQueryTests {
assertThat(li.get(0)).as("First row is Integer").isEqualTo(11);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -151,10 +156,13 @@ public class JdbcClientQueryTests { @@ -151,10 +156,13 @@ public class JdbcClientQueryTests {
assertThat(map.get("age")).as("Row is Integer").isEqualTo(11);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
public void testQueryForObjectWithIndexedParamAndRowMapper() throws Exception {
public void testQueryForIntegerWithIndexedParamAndRowMapper() throws Exception {
given(resultSet.next()).willReturn(true, false);
given(resultSet.getInt(1)).willReturn(22);
@ -165,6 +173,9 @@ public class JdbcClientQueryTests { @@ -165,6 +173,9 @@ public class JdbcClientQueryTests {
assertThat(value).isEqualTo(22);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -179,10 +190,13 @@ public class JdbcClientQueryTests { @@ -179,10 +190,13 @@ public class JdbcClientQueryTests {
assertThat(value.get()).isEqualTo(22);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
public void testQueryForObjectWithIndexedParamAndInteger() throws Exception {
public void testQueryForIntegerWithIndexedParam() throws Exception {
given(resultSet.getMetaData()).willReturn(resultSetMetaData);
given(resultSet.next()).willReturn(true, false);
given(resultSet.getObject(1)).willReturn(22);
@ -194,6 +208,9 @@ public class JdbcClientQueryTests { @@ -194,6 +208,9 @@ public class JdbcClientQueryTests {
assertThat(value).isEqualTo(22);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -209,6 +226,15 @@ public class JdbcClientQueryTests { @@ -209,6 +226,15 @@ public class JdbcClientQueryTests {
assertThat(i).as("Return of an int").isEqualTo(22);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
public void testQueryForObjectWithIndexedParamAndList() {
assertThatIllegalArgumentException().isThrownBy(() ->
client.sql("SELECT AGE FROM CUSTMR WHERE ID IN (?)").param(Arrays.asList(3, 4)).query().singleValue());
}
@ -230,6 +256,9 @@ public class JdbcClientQueryTests { @@ -230,6 +256,9 @@ public class JdbcClientQueryTests {
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -243,6 +272,9 @@ public class JdbcClientQueryTests { @@ -243,6 +272,9 @@ public class JdbcClientQueryTests {
assertThat(li.size()).as("All rows returned").isEqualTo(0);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -259,6 +291,9 @@ public class JdbcClientQueryTests { @@ -259,6 +291,9 @@ public class JdbcClientQueryTests {
assertThat(li.get(0).get("age")).as("First row is Integer").isEqualTo(11);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -275,6 +310,9 @@ public class JdbcClientQueryTests { @@ -275,6 +310,9 @@ public class JdbcClientQueryTests {
assertThat(li.get(0)).as("First row is Integer").isEqualTo(11);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -290,10 +328,13 @@ public class JdbcClientQueryTests { @@ -290,10 +328,13 @@ public class JdbcClientQueryTests {
assertThat(map.get("age")).as("Row is Integer").isEqualTo(11);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
public void testQueryForObjectWithNamedParamAndRowMapper() throws Exception {
public void testQueryForIntegerWithNamedParamAndRowMapper() throws Exception {
given(resultSet.next()).willReturn(true, false);
given(resultSet.getInt(1)).willReturn(22);
@ -305,10 +346,13 @@ public class JdbcClientQueryTests { @@ -305,10 +346,13 @@ public class JdbcClientQueryTests {
assertThat(value).isEqualTo(22);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
public void testQueryForObjectWithNamedParamAndMappedSimpleValue() throws Exception {
public void testQueryForIntegerWithNamedParamAndMappedSimpleValue() throws Exception {
given(resultSet.getMetaData()).willReturn(resultSetMetaData);
given(resultSet.next()).willReturn(true, false);
given(resultSet.getInt(1)).willReturn(22);
@ -321,10 +365,13 @@ public class JdbcClientQueryTests { @@ -321,10 +365,13 @@ public class JdbcClientQueryTests {
assertThat(value).isEqualTo(22);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
public void testQueryForObjectWithNamedParamAndMappedRecord() throws Exception {
public void testQueryForMappedRecordWithNamedParam() throws Exception {
given(resultSet.getMetaData()).willReturn(resultSetMetaData);
given(resultSet.findColumn("age")).willReturn(1);
given(resultSet.next()).willReturn(true, false);
@ -338,10 +385,13 @@ public class JdbcClientQueryTests { @@ -338,10 +385,13 @@ public class JdbcClientQueryTests {
assertThat(value.age()).isEqualTo(22);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
public void testQueryForObjectWithNamedParamAndMappedFieldHolder() throws Exception {
public void testQueryForMappedFieldHolderWithNamedParam() throws Exception {
given(resultSet.getMetaData()).willReturn(resultSetMetaData);
given(resultSet.next()).willReturn(true, false);
given(resultSet.getInt(1)).willReturn(22);
@ -354,10 +404,13 @@ public class JdbcClientQueryTests { @@ -354,10 +404,13 @@ public class JdbcClientQueryTests {
assertThat(value.age).isEqualTo(22);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
public void testQueryForObjectWithNamedParamAndInteger() throws Exception {
public void testQueryForIntegerWithNamedParam() throws Exception {
given(resultSet.getMetaData()).willReturn(resultSetMetaData);
given(resultSet.next()).willReturn(true, false);
given(resultSet.getObject(1)).willReturn(22);
@ -369,10 +422,13 @@ public class JdbcClientQueryTests { @@ -369,10 +422,13 @@ public class JdbcClientQueryTests {
assertThat(value).isEqualTo(22);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
public void testQueryForObjectWithNamedParamAndList() throws Exception {
public void testQueryForIntegerWithNamedParamAndList() throws Exception {
given(resultSet.getMetaData()).willReturn(resultSetMetaData);
given(resultSet.next()).willReturn(true, false);
given(resultSet.getObject(1)).willReturn(22);
@ -384,10 +440,14 @@ public class JdbcClientQueryTests { @@ -384,10 +440,14 @@ public class JdbcClientQueryTests {
assertThat(value).isEqualTo(22);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID IN (?, ?)");
verify(preparedStatement).setObject(1, 3);
verify(preparedStatement).setObject(2, 4);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
public void testQueryForObjectWithNamedParamAndListOfExpressionLists() throws Exception {
public void testQueryForIntegerWithNamedParamAndListOfExpressionLists() throws Exception {
given(resultSet.getMetaData()).willReturn(resultSetMetaData);
given(resultSet.next()).willReturn(true, false);
given(resultSet.getObject(1)).willReturn(22);
@ -402,6 +462,12 @@ public class JdbcClientQueryTests { @@ -402,6 +462,12 @@ public class JdbcClientQueryTests {
assertThat(value).isEqualTo(22);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE (ID, NAME) IN ((?, ?), (?, ?))");
verify(preparedStatement).setObject(1, 3);
verify(preparedStatement).setString(2, "Rod");
verify(preparedStatement).setObject(3, 4);
verify(preparedStatement).setString(4, "Juergen");
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -417,6 +483,9 @@ public class JdbcClientQueryTests { @@ -417,6 +483,9 @@ public class JdbcClientQueryTests {
assertThat(i).as("Return of an int").isEqualTo(22);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -432,6 +501,9 @@ public class JdbcClientQueryTests { @@ -432,6 +501,9 @@ public class JdbcClientQueryTests {
assertThat(l).as("Return of a long").isEqualTo(87);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?");
verify(preparedStatement).setObject(1, 3, Types.INTEGER);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -448,6 +520,9 @@ public class JdbcClientQueryTests { @@ -448,6 +520,9 @@ public class JdbcClientQueryTests {
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID IN (?, ?)");
verify(preparedStatement).setObject(1, 3);
verify(preparedStatement).setObject(2, 5);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -463,6 +538,9 @@ public class JdbcClientQueryTests { @@ -463,6 +538,9 @@ public class JdbcClientQueryTests {
assertThat(l).as("Return of a long").isEqualTo(87);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?");
verify(preparedStatement).setObject(1, 3, Types.INTEGER);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}
@Test
@ -478,6 +556,9 @@ public class JdbcClientQueryTests { @@ -478,6 +556,9 @@ public class JdbcClientQueryTests {
assertThat(l).as("Return of a long").isEqualTo(87);
verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?");
verify(preparedStatement).setObject(1, 3, Types.INTEGER);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}

Loading…
Cancel
Save