Skip to content

Commit

Permalink
Reject iterable/collection value for positional parameter
Browse files Browse the repository at this point in the history
Closes gh-31215
  • Loading branch information
jhoeller committed Sep 13, 2023
1 parent 8f6c56f commit ae8a353
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public DefaultStatementSpec(String sql) {

@Override
public StatementSpec param(@Nullable Object value) {
validateIndexedParamValue(value);
this.indexedParams.add(value);
return this;
}
Expand All @@ -115,6 +116,7 @@ public StatementSpec param(int jdbcIndex, @Nullable Object value) {
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) {
Expand All @@ -129,6 +131,14 @@ public StatementSpec param(int jdbcIndex, @Nullable Object value) {
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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@

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;
Expand All @@ -46,10 +46,10 @@
*/
public class JdbcClientQueryTests {

private Connection connection = mock();

private DataSource dataSource = mock();

private Connection connection = mock();

private PreparedStatement preparedStatement = mock();

private ResultSet resultSet = mock();
Expand All @@ -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");
}


Expand All @@ -93,6 +86,9 @@ public void testQueryForListWithIndexedParam() throws Exception {

verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}

@Test
Expand All @@ -105,6 +101,9 @@ public void testQueryForListWithIndexedParamAndEmptyResult() throws Exception {
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
Expand All @@ -120,6 +119,9 @@ public void testQueryForListWithIndexedParamAndSingleRow() throws Exception {
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
Expand All @@ -136,6 +138,9 @@ public void testQueryForListWithIndexedParamAndSingleColumn() throws Exception {
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
Expand All @@ -151,10 +156,13 @@ public void testQueryForMapWithIndexedParamAndSingleRow() throws Exception {
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);

Expand All @@ -165,6 +173,9 @@ public void testQueryForObjectWithIndexedParamAndRowMapper() throws Exception {
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
Expand All @@ -179,10 +190,13 @@ public void testQueryForOptionalWithIndexedParamAndRowMapper() throws Exception
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);
Expand All @@ -194,6 +208,9 @@ public void testQueryForObjectWithIndexedParamAndInteger() throws Exception {
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
Expand All @@ -209,6 +226,15 @@ public void testQueryForIntWithIndexedParam() throws Exception {
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());
}


Expand All @@ -230,6 +256,9 @@ public void testQueryForListWithNamedParam() throws Exception {

verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID < ?");
verify(preparedStatement).setObject(1, 3);
verify(resultSet).close();
verify(preparedStatement).close();
verify(connection).close();
}

@Test
Expand All @@ -243,6 +272,9 @@ public void testQueryForListWithNamedParamAndEmptyResult() throws Exception {
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
Expand All @@ -259,6 +291,9 @@ public void testQueryForListWithNamedParamAndSingleRow() throws Exception {
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
Expand All @@ -275,6 +310,9 @@ public void testQueryForListWithNamedParamAndSingleColumn() throws Exception {
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
Expand All @@ -290,10 +328,13 @@ public void testQueryForMapWithNamedParamAndSingleRow() throws Exception {
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);

Expand All @@ -305,10 +346,13 @@ public void testQueryForObjectWithNamedParamAndRowMapper() throws Exception {
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);
Expand All @@ -321,10 +365,13 @@ public void testQueryForObjectWithNamedParamAndMappedSimpleValue() throws Except
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);
Expand All @@ -338,10 +385,13 @@ public void testQueryForObjectWithNamedParamAndMappedRecord() throws Exception {
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);
Expand All @@ -354,10 +404,13 @@ public void testQueryForObjectWithNamedParamAndMappedFieldHolder() throws Except
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);
Expand All @@ -369,10 +422,13 @@ public void testQueryForObjectWithNamedParamAndInteger() throws Exception {
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);
Expand All @@ -384,10 +440,14 @@ public void testQueryForObjectWithNamedParamAndList() throws Exception {
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);
Expand All @@ -402,6 +462,12 @@ public void testQueryForObjectWithNamedParamAndListOfExpressionLists() throws Ex
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
Expand All @@ -417,6 +483,9 @@ public void testQueryForIntWithNamedParam() throws Exception {
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
Expand All @@ -432,6 +501,9 @@ public void testQueryForLongWithParamBean() throws Exception {
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
Expand All @@ -448,6 +520,9 @@ public void testQueryForLongWithParamBeanWithCollection() throws Exception {
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
Expand All @@ -463,6 +538,9 @@ public void testQueryForLongWithParamRecord() throws Exception {
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
Expand All @@ -478,6 +556,9 @@ public void testQueryForLongWithParamFieldHolder() throws Exception {
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();
}


Expand Down

0 comments on commit ae8a353

Please sign in to comment.