diff --git a/client/trino-client/src/main/java/io/trino/client/uri/ConnectionProperties.java b/client/trino-client/src/main/java/io/trino/client/uri/ConnectionProperties.java index aaac81f2e4ca..b8c79c3d32e1 100644 --- a/client/trino-client/src/main/java/io/trino/client/uri/ConnectionProperties.java +++ b/client/trino-client/src/main/java/io/trino/client/uri/ConnectionProperties.java @@ -99,7 +99,7 @@ enum SslVerificationMode public static final ConnectionProperty DNS_RESOLVER_CONTEXT = new ResolverContext(); public static final ConnectionProperty HOSTNAME_IN_CERTIFICATE = new HostnameInCertificate(); public static final ConnectionProperty TIMEZONE = new TimeZone(); - public static final ConnectionProperty LEGACY_PREPARED_STATEMENTS = new LegacyPreparedStatements(); + public static final ConnectionProperty EXPLICIT_PREPARE = new ExplicitPrepare(); private static final Set> ALL_PROPERTIES = ImmutableSet.>builder() .add(USER) @@ -145,7 +145,7 @@ enum SslVerificationMode .add(DNS_RESOLVER_CONTEXT) .add(HOSTNAME_IN_CERTIFICATE) .add(TIMEZONE) - .add(LEGACY_PREPARED_STATEMENTS) + .add(EXPLICIT_PREPARE) .build(); private static final Map> KEY_LOOKUP = unmodifiableMap(ALL_PROPERTIES.stream() @@ -718,12 +718,12 @@ public TimeZone() } } - private static class LegacyPreparedStatements + private static class ExplicitPrepare extends AbstractConnectionProperty { - public LegacyPreparedStatements() + public ExplicitPrepare() { - super(PropertyName.LEGACY_PREPARED_STATEMENTS, NOT_REQUIRED, ALLOWED, BOOLEAN_CONVERTER); + super(PropertyName.EXPLICIT_PREPARE, NOT_REQUIRED, ALLOWED, BOOLEAN_CONVERTER); } } diff --git a/client/trino-client/src/main/java/io/trino/client/uri/PropertyName.java b/client/trino-client/src/main/java/io/trino/client/uri/PropertyName.java index 027633190034..b03b0064aa92 100644 --- a/client/trino-client/src/main/java/io/trino/client/uri/PropertyName.java +++ b/client/trino-client/src/main/java/io/trino/client/uri/PropertyName.java @@ -61,7 +61,7 @@ public enum PropertyName TRACE_TOKEN("traceToken"), SESSION_PROPERTIES("sessionProperties"), SOURCE("source"), - LEGACY_PREPARED_STATEMENTS("legacyPreparedStatements"), + EXPLICIT_PREPARE("explicitPrepare"), DNS_RESOLVER("dnsResolver"), DNS_RESOLVER_CONTEXT("dnsResolverContext"), HOSTNAME_IN_CERTIFICATE("hostnameInCertificate"), diff --git a/client/trino-client/src/main/java/io/trino/client/uri/TrinoUri.java b/client/trino-client/src/main/java/io/trino/client/uri/TrinoUri.java index 52407dd9fb56..ba461c5192d7 100644 --- a/client/trino-client/src/main/java/io/trino/client/uri/TrinoUri.java +++ b/client/trino-client/src/main/java/io/trino/client/uri/TrinoUri.java @@ -70,6 +70,7 @@ import static io.trino.client.uri.ConnectionProperties.DISABLE_COMPRESSION; import static io.trino.client.uri.ConnectionProperties.DNS_RESOLVER; import static io.trino.client.uri.ConnectionProperties.DNS_RESOLVER_CONTEXT; +import static io.trino.client.uri.ConnectionProperties.EXPLICIT_PREPARE; import static io.trino.client.uri.ConnectionProperties.EXTERNAL_AUTHENTICATION; import static io.trino.client.uri.ConnectionProperties.EXTERNAL_AUTHENTICATION_REDIRECT_HANDLERS; import static io.trino.client.uri.ConnectionProperties.EXTERNAL_AUTHENTICATION_TIMEOUT; @@ -86,7 +87,6 @@ import static io.trino.client.uri.ConnectionProperties.KERBEROS_REMOTE_SERVICE_NAME; import static io.trino.client.uri.ConnectionProperties.KERBEROS_SERVICE_PRINCIPAL_PATTERN; import static io.trino.client.uri.ConnectionProperties.KERBEROS_USE_CANONICAL_HOSTNAME; -import static io.trino.client.uri.ConnectionProperties.LEGACY_PREPARED_STATEMENTS; import static io.trino.client.uri.ConnectionProperties.PASSWORD; import static io.trino.client.uri.ConnectionProperties.ROLES; import static io.trino.client.uri.ConnectionProperties.SESSION_PROPERTIES; @@ -168,7 +168,7 @@ public class TrinoUri private Optional traceToken; private Optional> sessionProperties; private Optional source; - private Optional legacyPreparedStatements; + private Optional explicitPrepare; private Optional catalog = Optional.empty(); private Optional schema = Optional.empty(); @@ -222,7 +222,7 @@ private TrinoUri( Optional traceToken, Optional> sessionProperties, Optional source, - Optional legacyPreparedStatements) + Optional explicitPrepare) throws SQLException { this.uri = requireNonNull(uri, "uri is null"); @@ -275,7 +275,7 @@ private TrinoUri( this.traceToken = TRACE_TOKEN.getValueOrDefault(urlProperties, traceToken); this.sessionProperties = SESSION_PROPERTIES.getValueOrDefault(urlProperties, sessionProperties); this.source = SOURCE.getValueOrDefault(urlProperties, source); - this.legacyPreparedStatements = LEGACY_PREPARED_STATEMENTS.getValueOrDefault(urlProperties, legacyPreparedStatements); + this.explicitPrepare = EXPLICIT_PREPARE.getValueOrDefault(urlProperties, explicitPrepare); properties = buildProperties(); @@ -361,7 +361,7 @@ private Properties buildProperties() clientTags.ifPresent(value -> properties.setProperty(PropertyName.CLIENT_TAGS.toString(), value)); traceToken.ifPresent(value -> properties.setProperty(PropertyName.TRACE_TOKEN.toString(), value)); source.ifPresent(value -> properties.setProperty(PropertyName.SOURCE.toString(), value)); - legacyPreparedStatements.ifPresent(value -> properties.setProperty(PropertyName.LEGACY_PREPARED_STATEMENTS.toString(), value.toString())); + explicitPrepare.ifPresent(value -> properties.setProperty(PropertyName.EXPLICIT_PREPARE.toString(), value.toString())); return properties; } @@ -421,7 +421,7 @@ protected TrinoUri(URI uri, Properties driverProperties) this.traceToken = TRACE_TOKEN.getValue(properties); this.sessionProperties = SESSION_PROPERTIES.getValue(properties); this.source = SOURCE.getValue(properties); - this.legacyPreparedStatements = LEGACY_PREPARED_STATEMENTS.getValue(properties); + this.explicitPrepare = EXPLICIT_PREPARE.getValue(properties); // enable SSL by default for the trino schema and the standard port useSecureConnection = ssl.orElse(uri.getScheme().equals("https") || (uri.getScheme().equals("trino") && uri.getPort() == 443)); @@ -529,9 +529,9 @@ public Optional getSource() return source; } - public Optional getLegacyPreparedStatements() + public Optional getExplicitPrepare() { - return legacyPreparedStatements; + return explicitPrepare; } public boolean isCompressionDisabled() @@ -938,7 +938,7 @@ public static final class Builder private String traceToken; private Map sessionProperties; private String source; - private Boolean legacyPreparedStatements; + private Boolean explicitPrepare; private Builder() {} @@ -1227,9 +1227,9 @@ public Builder setSource(String source) return this; } - public Builder setLegacyPreparedStatements(Boolean legacyPreparedStatements) + public Builder setExplicitPrepare(Boolean explicitPrepare) { - this.legacyPreparedStatements = requireNonNull(legacyPreparedStatements, "legacyPreparedStatements is null"); + this.explicitPrepare = requireNonNull(explicitPrepare, "explicitPrepare is null"); return this; } @@ -1282,7 +1282,7 @@ public TrinoUri build() Optional.ofNullable(traceToken), Optional.ofNullable(sessionProperties), Optional.ofNullable(source), - Optional.ofNullable(legacyPreparedStatements)); + Optional.ofNullable(explicitPrepare)); } } } diff --git a/client/trino-jdbc/pom.xml b/client/trino-jdbc/pom.xml index 339ced4c64d9..b0482ce6843f 100644 --- a/client/trino-jdbc/pom.xml +++ b/client/trino-jdbc/pom.xml @@ -132,6 +132,12 @@ test + + io.airlift + junit-extensions + test + + io.airlift log @@ -258,6 +264,12 @@ test + + org.junit.jupiter + junit-jupiter-api + test + + org.postgresql postgresql diff --git a/client/trino-jdbc/src/main/java/io/trino/jdbc/TrinoConnection.java b/client/trino-jdbc/src/main/java/io/trino/jdbc/TrinoConnection.java index 4b7d38d88e9c..0864fa43e5cc 100644 --- a/client/trino-jdbc/src/main/java/io/trino/jdbc/TrinoConnection.java +++ b/client/trino-jdbc/src/main/java/io/trino/jdbc/TrinoConnection.java @@ -112,7 +112,7 @@ public class TrinoConnection private final AtomicReference transactionId = new AtomicReference<>(); private final Call.Factory httpCallFactory; private final Set statements = newSetFromMap(new ConcurrentHashMap<>()); - private boolean useLegacyPreparedStatements = true; + private boolean useExplicitPrepare = true; TrinoConnection(TrinoDriverUri uri, Call.Factory httpCallFactory) { @@ -146,7 +146,7 @@ public class TrinoConnection locale.set(Locale.getDefault()); sessionProperties.putAll(uri.getSessionProperties()); - uri.getLegacyPreparedStatements().ifPresent(value -> this.useLegacyPreparedStatements = value); + uri.getExplicitPrepare().ifPresent(value -> this.useExplicitPrepare = value); } @Override @@ -915,8 +915,8 @@ public void throwIfHeld() } } - public Boolean isUseLegacyPreparedStatements() + public boolean useExplicitPrepare() { - return this.useLegacyPreparedStatements; + return this.useExplicitPrepare; } } diff --git a/client/trino-jdbc/src/main/java/io/trino/jdbc/TrinoPreparedStatement.java b/client/trino-jdbc/src/main/java/io/trino/jdbc/TrinoPreparedStatement.java index f34cbe938ec5..a1e17775dde6 100644 --- a/client/trino-jdbc/src/main/java/io/trino/jdbc/TrinoPreparedStatement.java +++ b/client/trino-jdbc/src/main/java/io/trino/jdbc/TrinoPreparedStatement.java @@ -117,7 +117,7 @@ public class TrinoPreparedStatement super(connection, onClose); this.statementName = requireNonNull(statementName, "statementName is null"); this.originalSql = requireNonNull(sql, "sql is null"); - if (connection().isUseLegacyPreparedStatements()) { + if (connection().useExplicitPrepare()) { super.execute(format("PREPARE %s FROM %s", statementName, sql)); prepareStatementExecuted = true; } @@ -1020,7 +1020,7 @@ private String getLegacySql(String statementName, List values) private String getExecuteSql(String statementName, List values) throws SQLException { - return connection().isUseLegacyPreparedStatements() + return connection().useExplicitPrepare() ? getLegacySql(statementName, values) : getExecuteImmediateSql(values); } @@ -1147,7 +1147,7 @@ private static List getDescribeOutputColumnInfoList(ResultSet result } /* - When isUseLegacyPreparedStatements is disabled, the PREPARE statement won't be executed unless needed + When explicitPrepare is disabled, the PREPARE statement won't be executed unless needed e.g. when getMetadata() or getParameterMetadata() are called. When needed, just make sure it is executed only once, even if the metadata methods are called many times */ diff --git a/client/trino-jdbc/src/test/java/io/trino/jdbc/TestJdbcPreparedStatement.java b/client/trino-jdbc/src/test/java/io/trino/jdbc/TestJdbcPreparedStatement.java index d549d7ae922c..60f1f0c3f9de 100644 --- a/client/trino-jdbc/src/test/java/io/trino/jdbc/TestJdbcPreparedStatement.java +++ b/client/trino-jdbc/src/test/java/io/trino/jdbc/TestJdbcPreparedStatement.java @@ -22,10 +22,10 @@ import io.trino.plugin.blackhole.BlackHolePlugin; import io.trino.plugin.memory.MemoryPlugin; import io.trino.server.testing.TestingTrinoServer; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; import java.math.BigDecimal; import java.math.BigInteger; @@ -69,24 +69,20 @@ import static java.util.Objects.requireNonNull; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; +@TestInstance(PER_CLASS) public class TestJdbcPreparedStatement { - @DataProvider - public Object[][] legacyPreparedStatementProvider() - { - return new Object[][] {{true}, {false}}; - } - private static final int HEADER_SIZE_LIMIT = 16 * 1024; private TestingTrinoServer server; - @BeforeClass + @BeforeAll public void setup() throws Exception { @@ -109,7 +105,7 @@ public void setup() } } - @AfterClass(alwaysRun = true) + @AfterAll public void tearDown() throws Exception { @@ -117,11 +113,18 @@ public void tearDown() server = null; } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testExecuteQuery(boolean useLegacyPreparedStatements) + @Test + public void testExecuteQuery() + throws Exception + { + testExecuteQuery(false); + testExecuteQuery(true); + } + + private void testExecuteQuery(boolean explicitPrepare) throws Exception { - try (Connection connection = createConnection(useLegacyPreparedStatements); + try (Connection connection = createConnection(explicitPrepare); PreparedStatement statement = connection.prepareStatement("SELECT ?, ?")) { statement.setInt(1, 123); statement.setString(2, "hello"); @@ -143,11 +146,18 @@ public void testExecuteQuery(boolean useLegacyPreparedStatements) } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testGetMetadata(boolean useLegacyPreparedStatements) + @Test + public void testGetMetadata() + throws Exception + { + testGetMetadata(true); + testGetMetadata(false); + } + + private void testGetMetadata(boolean explicitPrepare) throws Exception { - try (Connection connection = createConnection("blackhole", "blackhole", useLegacyPreparedStatements)) { + try (Connection connection = createConnection("blackhole", "blackhole", explicitPrepare)) { try (Statement statement = connection.createStatement()) { statement.execute("CREATE TABLE test_get_metadata (" + "c_boolean boolean, " + @@ -201,11 +211,18 @@ public void testGetMetadata(boolean useLegacyPreparedStatements) } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testGetParameterMetaData(boolean useLegacyPreparedStatements) + @Test + public void testGetParameterMetaData() + throws Exception + { + testGetParameterMetaData(true); + testGetParameterMetaData(false); + } + + private void testGetParameterMetaData(boolean explicitPrepare) throws Exception { - try (Connection connection = createConnection("blackhole", "blackhole", useLegacyPreparedStatements)) { + try (Connection connection = createConnection("blackhole", "blackhole", explicitPrepare)) { try (Statement statement = connection.createStatement()) { statement.execute("CREATE TABLE test_get_parameterMetaData (" + "c_boolean boolean, " + @@ -389,11 +406,18 @@ public void testGetClientTypeSignatureFromTypeString() assertEquals(actualClientTypeSignature, expectedClientTypeSignature); } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testDeallocate(boolean useLegacyPreparedStatements) + @Test + public void testDeallocate() + throws Exception + { + testDeallocate(true); + testDeallocate(false); + } + + private void testDeallocate(boolean explicitPrepare) throws Exception { - try (Connection connection = createConnection(useLegacyPreparedStatements)) { + try (Connection connection = createConnection(explicitPrepare)) { for (int i = 0; i < 200; i++) { try { connection.prepareStatement("SELECT '" + repeat("a", 300) + "'").close(); @@ -405,23 +429,37 @@ public void testDeallocate(boolean useLegacyPreparedStatements) } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testCloseIdempotency(boolean useLegacyPreparedStatements) + @Test + public void testCloseIdempotency() + throws Exception + { + testCloseIdempotency(true); + testCloseIdempotency(false); + } + + private void testCloseIdempotency(boolean explicitPrepare) throws Exception { - try (Connection connection = createConnection(useLegacyPreparedStatements)) { + try (Connection connection = createConnection(explicitPrepare)) { PreparedStatement statement = connection.prepareStatement("SELECT 123"); statement.close(); statement.close(); } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testLargePreparedStatement(boolean useLegacyPreparedStatements) + @Test + public void testLargePreparedStatement() + throws Exception + { + testLargePreparedStatement(true); + testLargePreparedStatement(false); + } + + private void testLargePreparedStatement(boolean explicitPrepare) throws Exception { int elements = HEADER_SIZE_LIMIT + 1; - try (Connection connection = createConnection(useLegacyPreparedStatements); + try (Connection connection = createConnection(explicitPrepare); PreparedStatement statement = connection.prepareStatement("VALUES ?" + repeat(", ?", elements - 1))) { for (int i = 0; i < elements; i++) { statement.setLong(i + 1, i); @@ -433,11 +471,18 @@ public void testLargePreparedStatement(boolean useLegacyPreparedStatements) } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testExecuteUpdate(boolean useLegacyPreparedStatements) + @Test + public void testExecuteUpdate() + throws Exception + { + testExecuteUpdate(true); + testExecuteUpdate(false); + } + + public void testExecuteUpdate(boolean explicitPrepare) throws Exception { - try (Connection connection = createConnection("blackhole", "blackhole", useLegacyPreparedStatements)) { + try (Connection connection = createConnection("blackhole", "blackhole", explicitPrepare)) { try (Statement statement = connection.createStatement()) { statement.execute("CREATE TABLE test_execute_update (" + "c_boolean boolean, " + @@ -472,11 +517,18 @@ public void testExecuteUpdate(boolean useLegacyPreparedStatements) } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testExecuteBatch(boolean useLegacyPreparedStatements) + @Test + public void testExecuteBatch() + throws Exception + { + testExecuteBatch(true); + testExecuteBatch(false); + } + + private void testExecuteBatch(boolean explicitPrepare) throws Exception { - try (Connection connection = createConnection("memory", "default", useLegacyPreparedStatements)) { + try (Connection connection = createConnection("memory", "default", explicitPrepare)) { try (Statement statement = connection.createStatement()) { statement.execute("CREATE TABLE test_execute_batch(c_int integer)"); } @@ -519,11 +571,18 @@ public void testExecuteBatch(boolean useLegacyPreparedStatements) } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testInvalidExecuteBatch(boolean useLegacyPreparedStatements) + @Test + public void testInvalidExecuteBatch() + throws Exception + { + testInvalidExecuteBatch(true); + testInvalidExecuteBatch(false); + } + + private void testInvalidExecuteBatch(boolean explicitPrepare) throws Exception { - try (Connection connection = createConnection("blackhole", "blackhole", useLegacyPreparedStatements)) { + try (Connection connection = createConnection("blackhole", "blackhole", explicitPrepare)) { try (Statement statement = connection.createStatement()) { statement.execute("CREATE TABLE test_invalid_execute_batch(c_int integer)"); } @@ -554,11 +613,18 @@ public void testInvalidExecuteBatch(boolean useLegacyPreparedStatements) } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testPrepareMultiple(boolean useLegacyPreparedStatements) + @Test + public void testPrepareMultiple() + throws Exception + { + testPrepareMultiple(true); + testPrepareMultiple(false); + } + + private void testPrepareMultiple(boolean explicitPrepare) throws Exception { - try (Connection connection = createConnection(useLegacyPreparedStatements); + try (Connection connection = createConnection(explicitPrepare); PreparedStatement statement1 = connection.prepareStatement("SELECT 123"); PreparedStatement statement2 = connection.prepareStatement("SELECT 456")) { try (ResultSet rs = statement1.executeQuery()) { @@ -575,12 +641,19 @@ public void testPrepareMultiple(boolean useLegacyPreparedStatements) } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testPrepareLarge(boolean useLegacyPreparedStatements) + @Test + public void testPrepareLarge() + throws Exception + { + testPrepareLarge(true); + testPrepareLarge(false); + } + + private void testPrepareLarge(boolean explicitPrepare) throws Exception { String sql = format("SELECT '%s' = '%s'", repeat("x", 100_000), repeat("y", 100_000)); - try (Connection connection = createConnection(useLegacyPreparedStatements); + try (Connection connection = createConnection(explicitPrepare); PreparedStatement statement = connection.prepareStatement(sql); ResultSet rs = statement.executeQuery()) { assertTrue(rs.next()); @@ -589,47 +662,54 @@ public void testPrepareLarge(boolean useLegacyPreparedStatements) } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testSetNull(boolean useLegacyPreparedStatements) + @Test + public void testSetNull() + throws Exception + { + testSetNull(true); + testSetNull(false); + } + + private void testSetNull(boolean explicitPrepare) throws Exception { - assertSetNull(Types.BOOLEAN, useLegacyPreparedStatements); - assertSetNull(Types.BIT, Types.BOOLEAN, useLegacyPreparedStatements); - assertSetNull(Types.TINYINT, useLegacyPreparedStatements); - assertSetNull(Types.SMALLINT, useLegacyPreparedStatements); - assertSetNull(Types.INTEGER, useLegacyPreparedStatements); - assertSetNull(Types.BIGINT, useLegacyPreparedStatements); - assertSetNull(Types.REAL, useLegacyPreparedStatements); - assertSetNull(Types.FLOAT, Types.REAL, useLegacyPreparedStatements); - assertSetNull(Types.DECIMAL, useLegacyPreparedStatements); - assertSetNull(Types.NUMERIC, Types.DECIMAL, useLegacyPreparedStatements); - assertSetNull(Types.CHAR, useLegacyPreparedStatements); - assertSetNull(Types.NCHAR, Types.CHAR, useLegacyPreparedStatements); - assertSetNull(Types.VARCHAR, Types.VARCHAR, useLegacyPreparedStatements); - assertSetNull(Types.NVARCHAR, Types.VARCHAR, useLegacyPreparedStatements); - assertSetNull(Types.LONGVARCHAR, Types.VARCHAR, useLegacyPreparedStatements); - assertSetNull(Types.VARCHAR, Types.VARCHAR, useLegacyPreparedStatements); - assertSetNull(Types.CLOB, Types.VARCHAR, useLegacyPreparedStatements); - assertSetNull(Types.NCLOB, Types.VARCHAR, useLegacyPreparedStatements); - assertSetNull(Types.VARBINARY, Types.VARBINARY, useLegacyPreparedStatements); - assertSetNull(Types.VARBINARY, useLegacyPreparedStatements); - assertSetNull(Types.BLOB, Types.VARBINARY, useLegacyPreparedStatements); - assertSetNull(Types.DATE, useLegacyPreparedStatements); - assertSetNull(Types.TIME, useLegacyPreparedStatements); - assertSetNull(Types.TIMESTAMP, useLegacyPreparedStatements); - assertSetNull(Types.NULL, useLegacyPreparedStatements); - } - - private void assertSetNull(int sqlType, boolean useLegacyPreparedStatements) + assertSetNull(Types.BOOLEAN, explicitPrepare); + assertSetNull(Types.BIT, Types.BOOLEAN, explicitPrepare); + assertSetNull(Types.TINYINT, explicitPrepare); + assertSetNull(Types.SMALLINT, explicitPrepare); + assertSetNull(Types.INTEGER, explicitPrepare); + assertSetNull(Types.BIGINT, explicitPrepare); + assertSetNull(Types.REAL, explicitPrepare); + assertSetNull(Types.FLOAT, Types.REAL, explicitPrepare); + assertSetNull(Types.DECIMAL, explicitPrepare); + assertSetNull(Types.NUMERIC, Types.DECIMAL, explicitPrepare); + assertSetNull(Types.CHAR, explicitPrepare); + assertSetNull(Types.NCHAR, Types.CHAR, explicitPrepare); + assertSetNull(Types.VARCHAR, Types.VARCHAR, explicitPrepare); + assertSetNull(Types.NVARCHAR, Types.VARCHAR, explicitPrepare); + assertSetNull(Types.LONGVARCHAR, Types.VARCHAR, explicitPrepare); + assertSetNull(Types.VARCHAR, Types.VARCHAR, explicitPrepare); + assertSetNull(Types.CLOB, Types.VARCHAR, explicitPrepare); + assertSetNull(Types.NCLOB, Types.VARCHAR, explicitPrepare); + assertSetNull(Types.VARBINARY, Types.VARBINARY, explicitPrepare); + assertSetNull(Types.VARBINARY, explicitPrepare); + assertSetNull(Types.BLOB, Types.VARBINARY, explicitPrepare); + assertSetNull(Types.DATE, explicitPrepare); + assertSetNull(Types.TIME, explicitPrepare); + assertSetNull(Types.TIMESTAMP, explicitPrepare); + assertSetNull(Types.NULL, explicitPrepare); + } + + private void assertSetNull(int sqlType, boolean explicitPrepare) throws SQLException { - assertSetNull(sqlType, sqlType, useLegacyPreparedStatements); + assertSetNull(sqlType, sqlType, explicitPrepare); } - private void assertSetNull(int sqlType, int expectedSqlType, boolean useLegacyPreparedStatements) + private void assertSetNull(int sqlType, int expectedSqlType, boolean explicitPrepare) throws SQLException { - try (Connection connection = createConnection(useLegacyPreparedStatements); + try (Connection connection = createConnection(explicitPrepare); PreparedStatement statement = connection.prepareStatement("SELECT ?")) { statement.setNull(1, sqlType); @@ -644,219 +724,296 @@ private void assertSetNull(int sqlType, int expectedSqlType, boolean useLegacyPr } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertBoolean(boolean useLegacyPreparedStatements) + @Test + public void testConvertBoolean() + throws SQLException + { + testConvertBoolean(true); + testConvertBoolean(false); + } + + private void testConvertBoolean(boolean explicitPrepare) throws SQLException { - assertBind((ps, i) -> ps.setBoolean(i, true), useLegacyPreparedStatements).roundTripsAs(Types.BOOLEAN, true); - assertBind((ps, i) -> ps.setBoolean(i, false), useLegacyPreparedStatements).roundTripsAs(Types.BOOLEAN, false); - assertBind((ps, i) -> ps.setObject(i, true), useLegacyPreparedStatements).roundTripsAs(Types.BOOLEAN, true); - assertBind((ps, i) -> ps.setObject(i, false), useLegacyPreparedStatements).roundTripsAs(Types.BOOLEAN, false); + assertBind((ps, i) -> ps.setBoolean(i, true), explicitPrepare).roundTripsAs(Types.BOOLEAN, true); + assertBind((ps, i) -> ps.setBoolean(i, false), explicitPrepare).roundTripsAs(Types.BOOLEAN, false); + assertBind((ps, i) -> ps.setObject(i, true), explicitPrepare).roundTripsAs(Types.BOOLEAN, true); + assertBind((ps, i) -> ps.setObject(i, false), explicitPrepare).roundTripsAs(Types.BOOLEAN, false); for (int type : asList(Types.BOOLEAN, Types.BIT)) { - assertBind((ps, i) -> ps.setObject(i, true, type), useLegacyPreparedStatements).roundTripsAs(Types.BOOLEAN, true); - assertBind((ps, i) -> ps.setObject(i, false, type), useLegacyPreparedStatements).roundTripsAs(Types.BOOLEAN, false); - assertBind((ps, i) -> ps.setObject(i, 13, type), useLegacyPreparedStatements).roundTripsAs(Types.BOOLEAN, true); - assertBind((ps, i) -> ps.setObject(i, 0, type), useLegacyPreparedStatements).roundTripsAs(Types.BOOLEAN, false); - assertBind((ps, i) -> ps.setObject(i, "1", type), useLegacyPreparedStatements).roundTripsAs(Types.BOOLEAN, true); - assertBind((ps, i) -> ps.setObject(i, "true", type), useLegacyPreparedStatements).roundTripsAs(Types.BOOLEAN, true); - assertBind((ps, i) -> ps.setObject(i, "0", type), useLegacyPreparedStatements).roundTripsAs(Types.BOOLEAN, false); - assertBind((ps, i) -> ps.setObject(i, "false", type), useLegacyPreparedStatements).roundTripsAs(Types.BOOLEAN, false); + assertBind((ps, i) -> ps.setObject(i, true, type), explicitPrepare).roundTripsAs(Types.BOOLEAN, true); + assertBind((ps, i) -> ps.setObject(i, false, type), explicitPrepare).roundTripsAs(Types.BOOLEAN, false); + assertBind((ps, i) -> ps.setObject(i, 13, type), explicitPrepare).roundTripsAs(Types.BOOLEAN, true); + assertBind((ps, i) -> ps.setObject(i, 0, type), explicitPrepare).roundTripsAs(Types.BOOLEAN, false); + assertBind((ps, i) -> ps.setObject(i, "1", type), explicitPrepare).roundTripsAs(Types.BOOLEAN, true); + assertBind((ps, i) -> ps.setObject(i, "true", type), explicitPrepare).roundTripsAs(Types.BOOLEAN, true); + assertBind((ps, i) -> ps.setObject(i, "0", type), explicitPrepare).roundTripsAs(Types.BOOLEAN, false); + assertBind((ps, i) -> ps.setObject(i, "false", type), explicitPrepare).roundTripsAs(Types.BOOLEAN, false); } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertTinyint(boolean useLegacyPreparedStatements) + @Test + public void testConvertTinyint() + throws SQLException + { + testConvertTinyint(true); + testConvertTinyint(false); + } + + private void testConvertTinyint(boolean explicitPrepare) + throws SQLException + { + assertBind((ps, i) -> ps.setByte(i, (byte) 123), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 123); + assertBind((ps, i) -> ps.setObject(i, (byte) 123), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 123); + assertBind((ps, i) -> ps.setObject(i, (byte) 123, Types.TINYINT), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 123); + assertBind((ps, i) -> ps.setObject(i, (short) 123, Types.TINYINT), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 123); + assertBind((ps, i) -> ps.setObject(i, 123, Types.TINYINT), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 123); + assertBind((ps, i) -> ps.setObject(i, 123L, Types.TINYINT), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 123); + assertBind((ps, i) -> ps.setObject(i, 123.9f, Types.TINYINT), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 123); + assertBind((ps, i) -> ps.setObject(i, 123.9d, Types.TINYINT), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 123); + assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), Types.TINYINT), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 123); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), Types.TINYINT), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 123); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), Types.TINYINT), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 123); + assertBind((ps, i) -> ps.setObject(i, "123", Types.TINYINT), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 123); + assertBind((ps, i) -> ps.setObject(i, true, Types.TINYINT), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 1); + assertBind((ps, i) -> ps.setObject(i, false, Types.TINYINT), explicitPrepare).roundTripsAs(Types.TINYINT, (byte) 0); + } + + @Test + public void testConvertSmallint() + throws SQLException + { + testConvertSmallint(true); + testConvertSmallint(false); + } + + private void testConvertSmallint(boolean explicitPrepare) + throws SQLException + { + assertBind((ps, i) -> ps.setShort(i, (short) 123), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 123); + assertBind((ps, i) -> ps.setObject(i, (short) 123), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 123); + assertBind((ps, i) -> ps.setObject(i, (byte) 123, Types.SMALLINT), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 123); + assertBind((ps, i) -> ps.setObject(i, (short) 123, Types.SMALLINT), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 123); + assertBind((ps, i) -> ps.setObject(i, 123, Types.SMALLINT), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 123); + assertBind((ps, i) -> ps.setObject(i, 123L, Types.SMALLINT), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 123); + assertBind((ps, i) -> ps.setObject(i, 123.9f, Types.SMALLINT), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 123); + assertBind((ps, i) -> ps.setObject(i, 123.9d, Types.SMALLINT), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 123); + assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), Types.SMALLINT), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 123); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), Types.SMALLINT), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 123); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), Types.SMALLINT), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 123); + assertBind((ps, i) -> ps.setObject(i, "123", Types.SMALLINT), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 123); + assertBind((ps, i) -> ps.setObject(i, true, Types.SMALLINT), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 1); + assertBind((ps, i) -> ps.setObject(i, false, Types.SMALLINT), explicitPrepare).roundTripsAs(Types.SMALLINT, (short) 0); + } + + @Test + public void testConvertInteger() + throws SQLException + { + testConvertInteger(true); + testConvertInteger(false); + } + + private void testConvertInteger(boolean explicitPrepare) throws SQLException { - assertBind((ps, i) -> ps.setByte(i, (byte) 123), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 123); - assertBind((ps, i) -> ps.setObject(i, (byte) 123), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 123); - assertBind((ps, i) -> ps.setObject(i, (byte) 123, Types.TINYINT), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 123); - assertBind((ps, i) -> ps.setObject(i, (short) 123, Types.TINYINT), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 123); - assertBind((ps, i) -> ps.setObject(i, 123, Types.TINYINT), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 123); - assertBind((ps, i) -> ps.setObject(i, 123L, Types.TINYINT), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 123); - assertBind((ps, i) -> ps.setObject(i, 123.9f, Types.TINYINT), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 123); - assertBind((ps, i) -> ps.setObject(i, 123.9d, Types.TINYINT), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 123); - assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), Types.TINYINT), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 123); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), Types.TINYINT), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 123); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), Types.TINYINT), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 123); - assertBind((ps, i) -> ps.setObject(i, "123", Types.TINYINT), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 123); - assertBind((ps, i) -> ps.setObject(i, true, Types.TINYINT), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 1); - assertBind((ps, i) -> ps.setObject(i, false, Types.TINYINT), useLegacyPreparedStatements).roundTripsAs(Types.TINYINT, (byte) 0); - } - - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertSmallint(boolean useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setInt(i, 123), explicitPrepare).roundTripsAs(Types.INTEGER, 123); + assertBind((ps, i) -> ps.setObject(i, 123), explicitPrepare).roundTripsAs(Types.INTEGER, 123); + assertBind((ps, i) -> ps.setObject(i, (byte) 123, Types.INTEGER), explicitPrepare).roundTripsAs(Types.INTEGER, 123); + assertBind((ps, i) -> ps.setObject(i, (byte) 123, Types.INTEGER), explicitPrepare).roundTripsAs(Types.INTEGER, 123); + assertBind((ps, i) -> ps.setObject(i, (short) 123, Types.INTEGER), explicitPrepare).roundTripsAs(Types.INTEGER, 123); + assertBind((ps, i) -> ps.setObject(i, 123, Types.INTEGER), explicitPrepare).roundTripsAs(Types.INTEGER, 123); + assertBind((ps, i) -> ps.setObject(i, 123L, Types.INTEGER), explicitPrepare).roundTripsAs(Types.INTEGER, 123); + assertBind((ps, i) -> ps.setObject(i, 123.9f, Types.INTEGER), explicitPrepare).roundTripsAs(Types.INTEGER, 123); + assertBind((ps, i) -> ps.setObject(i, 123.9d, Types.INTEGER), explicitPrepare).roundTripsAs(Types.INTEGER, 123); + assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), Types.INTEGER), explicitPrepare).roundTripsAs(Types.INTEGER, 123); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), Types.INTEGER), explicitPrepare).roundTripsAs(Types.INTEGER, 123); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), Types.INTEGER), explicitPrepare).roundTripsAs(Types.INTEGER, 123); + assertBind((ps, i) -> ps.setObject(i, "123", Types.INTEGER), explicitPrepare).roundTripsAs(Types.INTEGER, 123); + assertBind((ps, i) -> ps.setObject(i, true, Types.INTEGER), explicitPrepare).roundTripsAs(Types.INTEGER, 1); + assertBind((ps, i) -> ps.setObject(i, false, Types.INTEGER), explicitPrepare).roundTripsAs(Types.INTEGER, 0); + } + + @Test + public void testConvertBigint() throws SQLException { - assertBind((ps, i) -> ps.setShort(i, (short) 123), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 123); - assertBind((ps, i) -> ps.setObject(i, (short) 123), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 123); - assertBind((ps, i) -> ps.setObject(i, (byte) 123, Types.SMALLINT), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 123); - assertBind((ps, i) -> ps.setObject(i, (short) 123, Types.SMALLINT), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 123); - assertBind((ps, i) -> ps.setObject(i, 123, Types.SMALLINT), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 123); - assertBind((ps, i) -> ps.setObject(i, 123L, Types.SMALLINT), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 123); - assertBind((ps, i) -> ps.setObject(i, 123.9f, Types.SMALLINT), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 123); - assertBind((ps, i) -> ps.setObject(i, 123.9d, Types.SMALLINT), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 123); - assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), Types.SMALLINT), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 123); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), Types.SMALLINT), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 123); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), Types.SMALLINT), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 123); - assertBind((ps, i) -> ps.setObject(i, "123", Types.SMALLINT), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 123); - assertBind((ps, i) -> ps.setObject(i, true, Types.SMALLINT), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 1); - assertBind((ps, i) -> ps.setObject(i, false, Types.SMALLINT), useLegacyPreparedStatements).roundTripsAs(Types.SMALLINT, (short) 0); - } - - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertInteger(boolean useLegacyPreparedStatements) + testConvertBigint(true); + testConvertBigint(false); + } + + private void testConvertBigint(boolean explicitPrepare) throws SQLException { - assertBind((ps, i) -> ps.setInt(i, 123), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 123); - assertBind((ps, i) -> ps.setObject(i, 123), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 123); - assertBind((ps, i) -> ps.setObject(i, (byte) 123, Types.INTEGER), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 123); - assertBind((ps, i) -> ps.setObject(i, (byte) 123, Types.INTEGER), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 123); - assertBind((ps, i) -> ps.setObject(i, (short) 123, Types.INTEGER), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 123); - assertBind((ps, i) -> ps.setObject(i, 123, Types.INTEGER), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 123); - assertBind((ps, i) -> ps.setObject(i, 123L, Types.INTEGER), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 123); - assertBind((ps, i) -> ps.setObject(i, 123.9f, Types.INTEGER), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 123); - assertBind((ps, i) -> ps.setObject(i, 123.9d, Types.INTEGER), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 123); - assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), Types.INTEGER), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 123); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), Types.INTEGER), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 123); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), Types.INTEGER), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 123); - assertBind((ps, i) -> ps.setObject(i, "123", Types.INTEGER), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 123); - assertBind((ps, i) -> ps.setObject(i, true, Types.INTEGER), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 1); - assertBind((ps, i) -> ps.setObject(i, false, Types.INTEGER), useLegacyPreparedStatements).roundTripsAs(Types.INTEGER, 0); - } - - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertBigint(boolean useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setLong(i, 123L), explicitPrepare).roundTripsAs(Types.BIGINT, 123L); + assertBind((ps, i) -> ps.setObject(i, 123L), explicitPrepare).roundTripsAs(Types.BIGINT, 123L); + assertBind((ps, i) -> ps.setObject(i, (byte) 123, Types.BIGINT), explicitPrepare).roundTripsAs(Types.BIGINT, 123L); + assertBind((ps, i) -> ps.setObject(i, (short) 123, Types.BIGINT), explicitPrepare).roundTripsAs(Types.BIGINT, 123L); + assertBind((ps, i) -> ps.setObject(i, 123, Types.BIGINT), explicitPrepare).roundTripsAs(Types.BIGINT, 123L); + assertBind((ps, i) -> ps.setObject(i, 123L, Types.BIGINT), explicitPrepare).roundTripsAs(Types.BIGINT, 123L); + assertBind((ps, i) -> ps.setObject(i, 123.9f, Types.BIGINT), explicitPrepare).roundTripsAs(Types.BIGINT, 123L); + assertBind((ps, i) -> ps.setObject(i, 123.9d, Types.BIGINT), explicitPrepare).roundTripsAs(Types.BIGINT, 123L); + assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), Types.BIGINT), explicitPrepare).roundTripsAs(Types.BIGINT, 123L); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), Types.BIGINT), explicitPrepare).roundTripsAs(Types.BIGINT, 123L); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), Types.BIGINT), explicitPrepare).roundTripsAs(Types.BIGINT, 123L); + assertBind((ps, i) -> ps.setObject(i, "123", Types.BIGINT), explicitPrepare).roundTripsAs(Types.BIGINT, 123L); + assertBind((ps, i) -> ps.setObject(i, true, Types.BIGINT), explicitPrepare).roundTripsAs(Types.BIGINT, 1L); + assertBind((ps, i) -> ps.setObject(i, false, Types.BIGINT), explicitPrepare).roundTripsAs(Types.BIGINT, 0L); + } + + @Test + public void testConvertReal() throws SQLException { - assertBind((ps, i) -> ps.setLong(i, 123L), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 123L); - assertBind((ps, i) -> ps.setObject(i, 123L), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 123L); - assertBind((ps, i) -> ps.setObject(i, (byte) 123, Types.BIGINT), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 123L); - assertBind((ps, i) -> ps.setObject(i, (short) 123, Types.BIGINT), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 123L); - assertBind((ps, i) -> ps.setObject(i, 123, Types.BIGINT), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 123L); - assertBind((ps, i) -> ps.setObject(i, 123L, Types.BIGINT), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 123L); - assertBind((ps, i) -> ps.setObject(i, 123.9f, Types.BIGINT), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 123L); - assertBind((ps, i) -> ps.setObject(i, 123.9d, Types.BIGINT), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 123L); - assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), Types.BIGINT), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 123L); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), Types.BIGINT), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 123L); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), Types.BIGINT), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 123L); - assertBind((ps, i) -> ps.setObject(i, "123", Types.BIGINT), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 123L); - assertBind((ps, i) -> ps.setObject(i, true, Types.BIGINT), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 1L); - assertBind((ps, i) -> ps.setObject(i, false, Types.BIGINT), useLegacyPreparedStatements).roundTripsAs(Types.BIGINT, 0L); - } - - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertReal(boolean useLegacyPreparedStatements) + testConvertReal(true); + testConvertReal(false); + } + + private void testConvertReal(boolean explicitPrepare) throws SQLException { - assertBind((ps, i) -> ps.setFloat(i, 4.2f), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 4.2f); - assertBind((ps, i) -> ps.setObject(i, 4.2f), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 4.2f); + assertBind((ps, i) -> ps.setFloat(i, 4.2f), explicitPrepare).roundTripsAs(Types.REAL, 4.2f); + assertBind((ps, i) -> ps.setObject(i, 4.2f), explicitPrepare).roundTripsAs(Types.REAL, 4.2f); for (int type : asList(Types.REAL, Types.FLOAT)) { - assertBind((ps, i) -> ps.setObject(i, (byte) 123, type), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 123.0f); - assertBind((ps, i) -> ps.setObject(i, (short) 123, type), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 123.0f); - assertBind((ps, i) -> ps.setObject(i, 123, type), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 123.0f); - assertBind((ps, i) -> ps.setObject(i, 123L, type), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 123.0f); - assertBind((ps, i) -> ps.setObject(i, 123.9f, type), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 123.9f); - assertBind((ps, i) -> ps.setObject(i, 123.9d, type), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 123.9f); - assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), type), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 123.0f); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), type), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 123.0f); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), type), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 123.9f); - assertBind((ps, i) -> ps.setObject(i, "4.2", type), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 4.2f); - assertBind((ps, i) -> ps.setObject(i, true, type), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 1.0f); - assertBind((ps, i) -> ps.setObject(i, false, type), useLegacyPreparedStatements).roundTripsAs(Types.REAL, 0.0f); + assertBind((ps, i) -> ps.setObject(i, (byte) 123, type), explicitPrepare).roundTripsAs(Types.REAL, 123.0f); + assertBind((ps, i) -> ps.setObject(i, (short) 123, type), explicitPrepare).roundTripsAs(Types.REAL, 123.0f); + assertBind((ps, i) -> ps.setObject(i, 123, type), explicitPrepare).roundTripsAs(Types.REAL, 123.0f); + assertBind((ps, i) -> ps.setObject(i, 123L, type), explicitPrepare).roundTripsAs(Types.REAL, 123.0f); + assertBind((ps, i) -> ps.setObject(i, 123.9f, type), explicitPrepare).roundTripsAs(Types.REAL, 123.9f); + assertBind((ps, i) -> ps.setObject(i, 123.9d, type), explicitPrepare).roundTripsAs(Types.REAL, 123.9f); + assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), type), explicitPrepare).roundTripsAs(Types.REAL, 123.0f); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), type), explicitPrepare).roundTripsAs(Types.REAL, 123.0f); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), type), explicitPrepare).roundTripsAs(Types.REAL, 123.9f); + assertBind((ps, i) -> ps.setObject(i, "4.2", type), explicitPrepare).roundTripsAs(Types.REAL, 4.2f); + assertBind((ps, i) -> ps.setObject(i, true, type), explicitPrepare).roundTripsAs(Types.REAL, 1.0f); + assertBind((ps, i) -> ps.setObject(i, false, type), explicitPrepare).roundTripsAs(Types.REAL, 0.0f); } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertDouble(boolean useLegacyPreparedStatements) + @Test + public void testConvertDouble() + throws SQLException + { + testConvertDouble(true); + testConvertDouble(false); + } + + private void testConvertDouble(boolean explicitPrepare) + throws SQLException + { + assertBind((ps, i) -> ps.setDouble(i, 4.2d), explicitPrepare).roundTripsAs(Types.DOUBLE, 4.2d); + assertBind((ps, i) -> ps.setObject(i, 4.2d), explicitPrepare).roundTripsAs(Types.DOUBLE, 4.2d); + assertBind((ps, i) -> ps.setObject(i, (byte) 123, Types.DOUBLE), explicitPrepare).roundTripsAs(Types.DOUBLE, 123.0d); + assertBind((ps, i) -> ps.setObject(i, (short) 123, Types.DOUBLE), explicitPrepare).roundTripsAs(Types.DOUBLE, 123.0d); + assertBind((ps, i) -> ps.setObject(i, 123, Types.DOUBLE), explicitPrepare).roundTripsAs(Types.DOUBLE, 123.0d); + assertBind((ps, i) -> ps.setObject(i, 123L, Types.DOUBLE), explicitPrepare).roundTripsAs(Types.DOUBLE, 123.0d); + assertBind((ps, i) -> ps.setObject(i, 123.9f, Types.DOUBLE), explicitPrepare).roundTripsAs(Types.DOUBLE, (double) 123.9f); + assertBind((ps, i) -> ps.setObject(i, 123.9d, Types.DOUBLE), explicitPrepare).roundTripsAs(Types.DOUBLE, 123.9d); + assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), Types.DOUBLE), explicitPrepare).roundTripsAs(Types.DOUBLE, 123.0d); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), Types.DOUBLE), explicitPrepare).roundTripsAs(Types.DOUBLE, 123.0d); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), Types.DOUBLE), explicitPrepare).roundTripsAs(Types.DOUBLE, 123.9d); + assertBind((ps, i) -> ps.setObject(i, "4.2", Types.DOUBLE), explicitPrepare).roundTripsAs(Types.DOUBLE, 4.2d); + assertBind((ps, i) -> ps.setObject(i, true, Types.DOUBLE), explicitPrepare).roundTripsAs(Types.DOUBLE, 1.0d); + assertBind((ps, i) -> ps.setObject(i, false, Types.DOUBLE), explicitPrepare).roundTripsAs(Types.DOUBLE, 0.0d); + } + + @Test + public void testConvertDecimal() throws SQLException { - assertBind((ps, i) -> ps.setDouble(i, 4.2d), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, 4.2d); - assertBind((ps, i) -> ps.setObject(i, 4.2d), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, 4.2d); - assertBind((ps, i) -> ps.setObject(i, (byte) 123, Types.DOUBLE), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, 123.0d); - assertBind((ps, i) -> ps.setObject(i, (short) 123, Types.DOUBLE), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, 123.0d); - assertBind((ps, i) -> ps.setObject(i, 123, Types.DOUBLE), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, 123.0d); - assertBind((ps, i) -> ps.setObject(i, 123L, Types.DOUBLE), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, 123.0d); - assertBind((ps, i) -> ps.setObject(i, 123.9f, Types.DOUBLE), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, (double) 123.9f); - assertBind((ps, i) -> ps.setObject(i, 123.9d, Types.DOUBLE), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, 123.9d); - assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), Types.DOUBLE), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, 123.0d); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), Types.DOUBLE), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, 123.0d); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), Types.DOUBLE), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, 123.9d); - assertBind((ps, i) -> ps.setObject(i, "4.2", Types.DOUBLE), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, 4.2d); - assertBind((ps, i) -> ps.setObject(i, true, Types.DOUBLE), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, 1.0d); - assertBind((ps, i) -> ps.setObject(i, false, Types.DOUBLE), useLegacyPreparedStatements).roundTripsAs(Types.DOUBLE, 0.0d); - } - - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertDecimal(boolean useLegacyPreparedStatements) + testConvertDecimal(true); + testConvertDecimal(false); + } + + private void testConvertDecimal(boolean explicitPrepare) throws SQLException { - assertBind((ps, i) -> ps.setBigDecimal(i, BigDecimal.valueOf(123)), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123)), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); + assertBind((ps, i) -> ps.setBigDecimal(i, BigDecimal.valueOf(123)), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123)), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); for (int type : asList(Types.DECIMAL, Types.NUMERIC)) { - assertBind((ps, i) -> ps.setObject(i, (byte) 123, type), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); - assertBind((ps, i) -> ps.setObject(i, (short) 123, type), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); - assertBind((ps, i) -> ps.setObject(i, 123, type), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); - assertBind((ps, i) -> ps.setObject(i, 123L, type), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); - assertBind((ps, i) -> ps.setObject(i, 123.9f, type), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123.9f)); - assertBind((ps, i) -> ps.setObject(i, 123.9d, type), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123.9d)); - assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), type), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), type), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9d), type), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123.9d)); - assertBind((ps, i) -> ps.setObject(i, "123", type), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); - assertBind((ps, i) -> ps.setObject(i, true, type), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(1)); - assertBind((ps, i) -> ps.setObject(i, false, type), useLegacyPreparedStatements).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(0)); + assertBind((ps, i) -> ps.setObject(i, (byte) 123, type), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); + assertBind((ps, i) -> ps.setObject(i, (short) 123, type), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); + assertBind((ps, i) -> ps.setObject(i, 123, type), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); + assertBind((ps, i) -> ps.setObject(i, 123L, type), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); + assertBind((ps, i) -> ps.setObject(i, 123.9f, type), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123.9f)); + assertBind((ps, i) -> ps.setObject(i, 123.9d, type), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123.9d)); + assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), type), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), type), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9d), type), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123.9d)); + assertBind((ps, i) -> ps.setObject(i, "123", type), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(123)); + assertBind((ps, i) -> ps.setObject(i, true, type), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(1)); + assertBind((ps, i) -> ps.setObject(i, false, type), explicitPrepare).roundTripsAs(Types.DECIMAL, BigDecimal.valueOf(0)); } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertVarchar(boolean useLegacyPreparedStatements) + @Test + public void testConvertVarchar() + throws SQLException + { + testConvertVarchar(true); + testConvertVarchar(false); + } + + private void testConvertVarchar(boolean explicitPrepare) throws SQLException { - assertBind((ps, i) -> ps.setString(i, "hello"), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "hello"); - assertBind((ps, i) -> ps.setObject(i, "hello"), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "hello"); + assertBind((ps, i) -> ps.setString(i, "hello"), explicitPrepare).roundTripsAs(Types.VARCHAR, "hello"); + assertBind((ps, i) -> ps.setObject(i, "hello"), explicitPrepare).roundTripsAs(Types.VARCHAR, "hello"); String unicodeAndNull = "abc'xyz\0\u2603\uD835\uDCABtest"; - assertBind((ps, i) -> ps.setString(i, unicodeAndNull), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, unicodeAndNull); + assertBind((ps, i) -> ps.setString(i, unicodeAndNull), explicitPrepare).roundTripsAs(Types.VARCHAR, unicodeAndNull); for (int type : asList(Types.CHAR, Types.NCHAR, Types.VARCHAR, Types.NVARCHAR, Types.LONGVARCHAR, Types.LONGNVARCHAR)) { - assertBind((ps, i) -> ps.setObject(i, (byte) 123, type), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "123"); - assertBind((ps, i) -> ps.setObject(i, (byte) 123, type), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "123"); - assertBind((ps, i) -> ps.setObject(i, (short) 123, type), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "123"); - assertBind((ps, i) -> ps.setObject(i, 123, type), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "123"); - assertBind((ps, i) -> ps.setObject(i, 123L, type), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "123"); - assertBind((ps, i) -> ps.setObject(i, 123.9f, type), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "123.9"); - assertBind((ps, i) -> ps.setObject(i, 123.9d, type), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "123.9"); - assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), type), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "123"); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), type), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "123"); - assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), type), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "123.9"); - assertBind((ps, i) -> ps.setObject(i, "hello", type), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "hello"); - assertBind((ps, i) -> ps.setObject(i, true, type), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "true"); - assertBind((ps, i) -> ps.setObject(i, false, type), useLegacyPreparedStatements).roundTripsAs(Types.VARCHAR, "false"); + assertBind((ps, i) -> ps.setObject(i, (byte) 123, type), explicitPrepare).roundTripsAs(Types.VARCHAR, "123"); + assertBind((ps, i) -> ps.setObject(i, (byte) 123, type), explicitPrepare).roundTripsAs(Types.VARCHAR, "123"); + assertBind((ps, i) -> ps.setObject(i, (short) 123, type), explicitPrepare).roundTripsAs(Types.VARCHAR, "123"); + assertBind((ps, i) -> ps.setObject(i, 123, type), explicitPrepare).roundTripsAs(Types.VARCHAR, "123"); + assertBind((ps, i) -> ps.setObject(i, 123L, type), explicitPrepare).roundTripsAs(Types.VARCHAR, "123"); + assertBind((ps, i) -> ps.setObject(i, 123.9f, type), explicitPrepare).roundTripsAs(Types.VARCHAR, "123.9"); + assertBind((ps, i) -> ps.setObject(i, 123.9d, type), explicitPrepare).roundTripsAs(Types.VARCHAR, "123.9"); + assertBind((ps, i) -> ps.setObject(i, BigInteger.valueOf(123), type), explicitPrepare).roundTripsAs(Types.VARCHAR, "123"); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123), type), explicitPrepare).roundTripsAs(Types.VARCHAR, "123"); + assertBind((ps, i) -> ps.setObject(i, BigDecimal.valueOf(123.9), type), explicitPrepare).roundTripsAs(Types.VARCHAR, "123.9"); + assertBind((ps, i) -> ps.setObject(i, "hello", type), explicitPrepare).roundTripsAs(Types.VARCHAR, "hello"); + assertBind((ps, i) -> ps.setObject(i, true, type), explicitPrepare).roundTripsAs(Types.VARCHAR, "true"); + assertBind((ps, i) -> ps.setObject(i, false, type), explicitPrepare).roundTripsAs(Types.VARCHAR, "false"); } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertVarbinary(boolean useLegacyPreparedStatements) + @Test + public void testConvertVarbinary() + throws SQLException + { + testConvertVarbinary(true); + testConvertVarbinary(false); + } + + private void testConvertVarbinary(boolean explicitPrepare) throws SQLException { String value = "abc\0xyz"; byte[] bytes = value.getBytes(UTF_8); - assertBind((ps, i) -> ps.setBytes(i, bytes), useLegacyPreparedStatements).roundTripsAs(Types.VARBINARY, bytes); - assertBind((ps, i) -> ps.setObject(i, bytes), useLegacyPreparedStatements).roundTripsAs(Types.VARBINARY, bytes); + assertBind((ps, i) -> ps.setBytes(i, bytes), explicitPrepare).roundTripsAs(Types.VARBINARY, bytes); + assertBind((ps, i) -> ps.setObject(i, bytes), explicitPrepare).roundTripsAs(Types.VARBINARY, bytes); for (int type : asList(Types.BINARY, Types.VARBINARY, Types.LONGVARBINARY)) { - assertBind((ps, i) -> ps.setObject(i, bytes, type), useLegacyPreparedStatements).roundTripsAs(Types.VARBINARY, bytes); - assertBind((ps, i) -> ps.setObject(i, value, type), useLegacyPreparedStatements).roundTripsAs(Types.VARBINARY, bytes); + assertBind((ps, i) -> ps.setObject(i, bytes, type), explicitPrepare).roundTripsAs(Types.VARBINARY, bytes); + assertBind((ps, i) -> ps.setObject(i, value, type), explicitPrepare).roundTripsAs(Types.VARBINARY, bytes); } } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertDate(boolean useLegacyPreparedStatements) + @Test + public void testConvertDate() + throws SQLException + { + testConvertDate(true); + testConvertDate(false); + } + + private void testConvertDate(boolean explicitPrepare) throws SQLException { LocalDate date = LocalDate.of(2001, 5, 6); @@ -865,78 +1022,92 @@ public void testConvertDate(boolean useLegacyPreparedStatements) LocalDateTime dateTime = LocalDateTime.of(date, LocalTime.of(12, 34, 56)); Timestamp sqlTimestamp = Timestamp.valueOf(dateTime); - assertBind((ps, i) -> ps.setDate(i, sqlDate), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setDate(i, sqlDate), explicitPrepare) .resultsIn("date", "DATE '2001-05-06'") .roundTripsAs(Types.DATE, sqlDate); - assertBind((ps, i) -> ps.setObject(i, sqlDate), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, sqlDate), explicitPrepare) .resultsIn("date", "DATE '2001-05-06'") .roundTripsAs(Types.DATE, sqlDate); - assertBind((ps, i) -> ps.setObject(i, sqlDate, Types.DATE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, sqlDate, Types.DATE), explicitPrepare) .resultsIn("date", "DATE '2001-05-06'") .roundTripsAs(Types.DATE, sqlDate); - assertBind((ps, i) -> ps.setObject(i, sqlTimestamp, Types.DATE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, sqlTimestamp, Types.DATE), explicitPrepare) .resultsIn("date", "DATE '2001-05-06'") .roundTripsAs(Types.DATE, sqlDate); - assertBind((ps, i) -> ps.setObject(i, javaDate, Types.DATE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, javaDate, Types.DATE), explicitPrepare) .resultsIn("date", "DATE '2001-05-06'") .roundTripsAs(Types.DATE, sqlDate); - assertBind((ps, i) -> ps.setObject(i, date, Types.DATE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, date, Types.DATE), explicitPrepare) .resultsIn("date", "DATE '2001-05-06'") .roundTripsAs(Types.DATE, sqlDate); - assertBind((ps, i) -> ps.setObject(i, dateTime, Types.DATE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, dateTime, Types.DATE), explicitPrepare) .resultsIn("date", "DATE '2001-05-06'") .roundTripsAs(Types.DATE, sqlDate); - assertBind((ps, i) -> ps.setObject(i, "2001-05-06", Types.DATE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "2001-05-06", Types.DATE), explicitPrepare) .resultsIn("date", "DATE '2001-05-06'") .roundTripsAs(Types.DATE, sqlDate); } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertLocalDate(boolean useLegacyPreparedStatements) + @Test + public void testConvertLocalDate() + throws SQLException + { + testConvertLocalDate(true); + testConvertLocalDate(false); + } + + private void testConvertLocalDate(boolean explicitPrepare) throws SQLException { LocalDate date = LocalDate.of(2001, 5, 6); - assertBind((ps, i) -> ps.setObject(i, date), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, date), explicitPrepare) .resultsIn("date", "DATE '2001-05-06'") .roundTripsAs(Types.DATE, Date.valueOf(date)); - assertBind((ps, i) -> ps.setObject(i, date, Types.DATE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, date, Types.DATE), explicitPrepare) .resultsIn("date", "DATE '2001-05-06'") .roundTripsAs(Types.DATE, Date.valueOf(date)); - assertBind((ps, i) -> ps.setObject(i, date, Types.TIME), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, date, Types.TIME), explicitPrepare) .isInvalid("Cannot convert instance of java.time.LocalDate to time"); - assertBind((ps, i) -> ps.setObject(i, date, Types.TIME_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, date, Types.TIME_WITH_TIMEZONE), explicitPrepare) .isInvalid("Cannot convert instance of java.time.LocalDate to time with time zone"); - assertBind((ps, i) -> ps.setObject(i, date, Types.TIMESTAMP), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, date, Types.TIMESTAMP), explicitPrepare) .isInvalid("Cannot convert instance of java.time.LocalDate to timestamp"); - assertBind((ps, i) -> ps.setObject(i, date, Types.TIMESTAMP_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, date, Types.TIMESTAMP_WITH_TIMEZONE), explicitPrepare) .isInvalid("Cannot convert instance of java.time.LocalDate to timestamp with time zone"); LocalDate jvmGapDate = LocalDate.of(1970, 1, 1); checkIsGap(ZoneId.systemDefault(), jvmGapDate.atTime(LocalTime.MIDNIGHT)); - assertBind((ps, i) -> ps.setObject(i, jvmGapDate), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, jvmGapDate), explicitPrepare) .resultsIn("date", "DATE '1970-01-01'") .roundTripsAs(Types.DATE, Date.valueOf(jvmGapDate)); - assertBind((ps, i) -> ps.setObject(i, jvmGapDate, Types.DATE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, jvmGapDate, Types.DATE), explicitPrepare) .roundTripsAs(Types.DATE, Date.valueOf(jvmGapDate)); } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertTime(boolean useLegacyPreparedStatements) + @Test + public void testConvertTime() + throws SQLException + { + testConvertTime(true); + testConvertTime(false); + } + + private void testConvertTime(boolean explicitPrepare) throws SQLException { LocalTime time = LocalTime.of(12, 34, 56); @@ -945,121 +1116,135 @@ public void testConvertTime(boolean useLegacyPreparedStatements) LocalDateTime dateTime = LocalDateTime.of(LocalDate.of(2001, 5, 6), time); Timestamp sqlTimestamp = Timestamp.valueOf(dateTime); - assertBind((ps, i) -> ps.setTime(i, sqlTime), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setTime(i, sqlTime), explicitPrepare) .resultsIn("time(3)", "TIME '12:34:56.000'") .roundTripsAs(Types.TIME, sqlTime); - assertBind((ps, i) -> ps.setObject(i, sqlTime), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, sqlTime), explicitPrepare) .resultsIn("time(3)", "TIME '12:34:56.000'") .roundTripsAs(Types.TIME, sqlTime); - assertBind((ps, i) -> ps.setObject(i, sqlTime, Types.TIME), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, sqlTime, Types.TIME), explicitPrepare) .resultsIn("time(3)", "TIME '12:34:56.000'") .roundTripsAs(Types.TIME, sqlTime); - assertBind((ps, i) -> ps.setObject(i, sqlTimestamp, Types.TIME), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, sqlTimestamp, Types.TIME), explicitPrepare) .resultsIn("time(3)", "TIME '12:34:56.000'") .roundTripsAs(Types.TIME, sqlTime); - assertBind((ps, i) -> ps.setObject(i, javaDate, Types.TIME), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, javaDate, Types.TIME), explicitPrepare) .resultsIn("time(3)", "TIME '12:34:56.000'") .roundTripsAs(Types.TIME, sqlTime); - assertBind((ps, i) -> ps.setObject(i, dateTime, Types.TIME), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, dateTime, Types.TIME), explicitPrepare) .resultsIn("time(0)", "TIME '12:34:56'") .roundTripsAs(Types.TIME, sqlTime); - assertBind((ps, i) -> ps.setObject(i, "12:34:56", Types.TIME), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "12:34:56", Types.TIME), explicitPrepare) .resultsIn("time(0)", "TIME '12:34:56'") .roundTripsAs(Types.TIME, sqlTime); - assertBind((ps, i) -> ps.setObject(i, "12:34:56.123", Types.TIME), useLegacyPreparedStatements).resultsIn("time(3)", "TIME '12:34:56.123'"); - assertBind((ps, i) -> ps.setObject(i, "12:34:56.123456", Types.TIME), useLegacyPreparedStatements).resultsIn("time(6)", "TIME '12:34:56.123456'"); + assertBind((ps, i) -> ps.setObject(i, "12:34:56.123", Types.TIME), explicitPrepare).resultsIn("time(3)", "TIME '12:34:56.123'"); + assertBind((ps, i) -> ps.setObject(i, "12:34:56.123456", Types.TIME), explicitPrepare).resultsIn("time(6)", "TIME '12:34:56.123456'"); - assertBind((ps, i) -> ps.setObject(i, "12:34:56.123456789", Types.TIME), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "12:34:56.123456789", Types.TIME), explicitPrepare) .resultsIn("time(9)", "TIME '12:34:56.123456789'"); - assertBind((ps, i) -> ps.setObject(i, "12:34:56.123456789012", Types.TIME), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "12:34:56.123456789012", Types.TIME), explicitPrepare) .resultsIn("time(12)", "TIME '12:34:56.123456789012'"); Time timeWithDecisecond = new Time(sqlTime.getTime() + 100); - assertBind((ps, i) -> ps.setObject(i, timeWithDecisecond), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, timeWithDecisecond), explicitPrepare) .resultsIn("time(3)", "TIME '12:34:56.100'") .roundTripsAs(Types.TIME, timeWithDecisecond); - assertBind((ps, i) -> ps.setObject(i, timeWithDecisecond, Types.TIME), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, timeWithDecisecond, Types.TIME), explicitPrepare) .resultsIn("time(3)", "TIME '12:34:56.100'") .roundTripsAs(Types.TIME, timeWithDecisecond); Time timeWithMillisecond = new Time(sqlTime.getTime() + 123); - assertBind((ps, i) -> ps.setObject(i, timeWithMillisecond), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, timeWithMillisecond), explicitPrepare) .resultsIn("time(3)", "TIME '12:34:56.123'") .roundTripsAs(Types.TIME, timeWithMillisecond); - assertBind((ps, i) -> ps.setObject(i, timeWithMillisecond, Types.TIME), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, timeWithMillisecond, Types.TIME), explicitPrepare) .resultsIn("time(3)", "TIME '12:34:56.123'") .roundTripsAs(Types.TIME, timeWithMillisecond); } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertTimeWithTimeZone(boolean useLegacyPreparedStatements) + @Test + public void testConvertTimeWithTimeZone() + throws SQLException + { + testConvertTimeWithTimeZone(true); + testConvertTimeWithTimeZone(false); + } + + private void testConvertTimeWithTimeZone(boolean explicitPrepare) throws SQLException { // zero fraction - assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 0, UTC), Types.TIME_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 0, UTC), Types.TIME_WITH_TIMEZONE), explicitPrepare) .resultsIn("time(0) with time zone", "TIME '12:34:56+00:00'") .roundTripsAs(Types.TIME_WITH_TIMEZONE, toSqlTime(LocalTime.of(5, 34, 56))); // setObject with implicit type - assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 0, UTC)), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 0, UTC)), explicitPrepare) .resultsIn("time(0) with time zone", "TIME '12:34:56+00:00'"); // setObject with JDBCType - assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 0, UTC), JDBCType.TIME_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 0, UTC), JDBCType.TIME_WITH_TIMEZONE), explicitPrepare) .resultsIn("time(0) with time zone", "TIME '12:34:56+00:00'"); // millisecond precision - assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 555_000_000, UTC), Types.TIME_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 555_000_000, UTC), Types.TIME_WITH_TIMEZONE), explicitPrepare) .resultsIn("time(3) with time zone", "TIME '12:34:56.555+00:00'") .roundTripsAs(Types.TIME_WITH_TIMEZONE, toSqlTime(LocalTime.of(5, 34, 56, 555_000_000))); // microsecond precision - assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 555_555_000, UTC), Types.TIME_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 555_555_000, UTC), Types.TIME_WITH_TIMEZONE), explicitPrepare) .resultsIn("time(6) with time zone", "TIME '12:34:56.555555+00:00'") .roundTripsAs(Types.TIME_WITH_TIMEZONE, toSqlTime(LocalTime.of(5, 34, 56, 556_000_000))); // nanosecond precision - assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 555_555_555, UTC), Types.TIME_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 555_555_555, UTC), Types.TIME_WITH_TIMEZONE), explicitPrepare) .resultsIn("time(9) with time zone", "TIME '12:34:56.555555555+00:00'") .roundTripsAs(Types.TIME_WITH_TIMEZONE, toSqlTime(LocalTime.of(5, 34, 56, 556_000_000))); // positive offset - assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 123_456_789, ZoneOffset.ofHoursMinutes(7, 35)), Types.TIME_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 123_456_789, ZoneOffset.ofHoursMinutes(7, 35)), Types.TIME_WITH_TIMEZONE), explicitPrepare) .resultsIn("time(9) with time zone", "TIME '12:34:56.123456789+07:35'"); // TODO (https://github.com/trinodb/trino/issues/6351) the result is not as expected here: // .roundTripsAs(Types.TIME_WITH_TIMEZONE, toSqlTime(LocalTime.of(20, 59, 56, 123_000_000))); // negative offset - assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 123_456_789, ZoneOffset.ofHoursMinutes(-7, -35)), Types.TIME_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, OffsetTime.of(12, 34, 56, 123_456_789, ZoneOffset.ofHoursMinutes(-7, -35)), Types.TIME_WITH_TIMEZONE), explicitPrepare) .resultsIn("time(9) with time zone", "TIME '12:34:56.123456789-07:35'") .roundTripsAs(Types.TIME_WITH_TIMEZONE, toSqlTime(LocalTime.of(13, 9, 56, 123_000_000))); // String as TIME WITH TIME ZONE - assertBind((ps, i) -> ps.setObject(i, "12:34:56.123 +05:45", Types.TIME_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "12:34:56.123 +05:45", Types.TIME_WITH_TIMEZONE), explicitPrepare) .resultsIn("time(3) with time zone", "TIME '12:34:56.123 +05:45'"); - assertBind((ps, i) -> ps.setObject(i, "12:34:56.123456 +05:45", Types.TIME_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "12:34:56.123456 +05:45", Types.TIME_WITH_TIMEZONE), explicitPrepare) .resultsIn("time(6) with time zone", "TIME '12:34:56.123456 +05:45'"); - assertBind((ps, i) -> ps.setObject(i, "12:34:56.123456789 +05:45", Types.TIME_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "12:34:56.123456789 +05:45", Types.TIME_WITH_TIMEZONE), explicitPrepare) .resultsIn("time(9) with time zone", "TIME '12:34:56.123456789 +05:45'"); - assertBind((ps, i) -> ps.setObject(i, "12:34:56.123456789012 +05:45", Types.TIME_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "12:34:56.123456789012 +05:45", Types.TIME_WITH_TIMEZONE), explicitPrepare) .resultsIn("time(12) with time zone", "TIME '12:34:56.123456789012 +05:45'"); } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertTimestamp(boolean useLegacyPreparedStatements) + @Test + public void testConvertTimestamp() + throws SQLException + { + testConvertTimestamp(true); + testConvertTimestamp(false); + } + + private void testConvertTimestamp(boolean explicitPrepare) throws SQLException { LocalDateTime dateTime = LocalDateTime.of(2001, 5, 6, 12, 34, 56); @@ -1069,162 +1254,176 @@ public void testConvertTimestamp(boolean useLegacyPreparedStatements) Timestamp sameInstantInWarsawZone = Timestamp.valueOf(dateTime.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("Europe/Warsaw")).toLocalDateTime()); java.util.Date javaDate = java.util.Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant()); - assertBind((ps, i) -> ps.setTimestamp(i, sqlTimestamp), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setTimestamp(i, sqlTimestamp), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 12:34:56.000'") .roundTripsAs(Types.TIMESTAMP, sqlTimestamp); - assertBind((ps, i) -> ps.setTimestamp(i, sqlTimestamp, null), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setTimestamp(i, sqlTimestamp, null), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 12:34:56.000'") .roundTripsAs(Types.TIMESTAMP, sqlTimestamp); - assertBind((ps, i) -> ps.setTimestamp(i, sqlTimestamp, Calendar.getInstance()), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setTimestamp(i, sqlTimestamp, Calendar.getInstance()), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 12:34:56.000'") .roundTripsAs(Types.TIMESTAMP, sqlTimestamp); - assertBind((ps, i) -> ps.setTimestamp(i, sqlTimestamp, Calendar.getInstance(TimeZone.getTimeZone(ZoneId.of("Europe/Warsaw")))), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setTimestamp(i, sqlTimestamp, Calendar.getInstance(TimeZone.getTimeZone(ZoneId.of("Europe/Warsaw")))), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 20:34:56.000'") .roundTripsAs(Types.TIMESTAMP, sameInstantInWarsawZone); - assertBind((ps, i) -> ps.setObject(i, sqlTimestamp), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, sqlTimestamp), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 12:34:56.000'") .roundTripsAs(Types.TIMESTAMP, sqlTimestamp); - assertBind((ps, i) -> ps.setObject(i, sqlDate, Types.TIMESTAMP), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, sqlDate, Types.TIMESTAMP), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 00:00:00.000'") .roundTripsAs(Types.TIMESTAMP, new Timestamp(sqlDate.getTime())); - assertBind((ps, i) -> ps.setObject(i, sqlTime, Types.TIMESTAMP), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, sqlTime, Types.TIMESTAMP), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '1970-01-01 12:34:56.000'") .roundTripsAs(Types.TIMESTAMP, new Timestamp(sqlTime.getTime())); - assertBind((ps, i) -> ps.setObject(i, sqlTimestamp, Types.TIMESTAMP), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, sqlTimestamp, Types.TIMESTAMP), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 12:34:56.000'") .roundTripsAs(Types.TIMESTAMP, sqlTimestamp); - assertBind((ps, i) -> ps.setObject(i, javaDate, Types.TIMESTAMP), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, javaDate, Types.TIMESTAMP), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 12:34:56.000'") .roundTripsAs(Types.TIMESTAMP, sqlTimestamp); - assertBind((ps, i) -> ps.setObject(i, dateTime, Types.TIMESTAMP), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, dateTime, Types.TIMESTAMP), explicitPrepare) .resultsIn("timestamp(0)", "TIMESTAMP '2001-05-06 12:34:56'") .roundTripsAs(Types.TIMESTAMP, sqlTimestamp); - assertBind((ps, i) -> ps.setObject(i, "2001-05-06 12:34:56", Types.TIMESTAMP), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "2001-05-06 12:34:56", Types.TIMESTAMP), explicitPrepare) .resultsIn("timestamp(0)", "TIMESTAMP '2001-05-06 12:34:56'") .roundTripsAs(Types.TIMESTAMP, sqlTimestamp); - assertBind((ps, i) -> ps.setObject(i, "2001-05-06 12:34:56.123", Types.TIMESTAMP), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "2001-05-06 12:34:56.123", Types.TIMESTAMP), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 12:34:56.123'"); - assertBind((ps, i) -> ps.setObject(i, "2001-05-06 12:34:56.123456", Types.TIMESTAMP), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "2001-05-06 12:34:56.123456", Types.TIMESTAMP), explicitPrepare) .resultsIn("timestamp(6)", "TIMESTAMP '2001-05-06 12:34:56.123456'"); - assertBind((ps, i) -> ps.setObject(i, "2001-05-06 12:34:56.123456789", Types.TIMESTAMP), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "2001-05-06 12:34:56.123456789", Types.TIMESTAMP), explicitPrepare) .resultsIn("timestamp(9)", "TIMESTAMP '2001-05-06 12:34:56.123456789'"); - assertBind((ps, i) -> ps.setObject(i, "2001-05-06 12:34:56.123456789012", Types.TIMESTAMP), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "2001-05-06 12:34:56.123456789012", Types.TIMESTAMP), explicitPrepare) .resultsIn("timestamp(12)", "TIMESTAMP '2001-05-06 12:34:56.123456789012'"); Timestamp timestampWithWithDecisecond = new Timestamp(sqlTimestamp.getTime() + 100); - assertBind((ps, i) -> ps.setTimestamp(i, timestampWithWithDecisecond), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setTimestamp(i, timestampWithWithDecisecond), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 12:34:56.100'") .roundTripsAs(Types.TIMESTAMP, timestampWithWithDecisecond); - assertBind((ps, i) -> ps.setObject(i, timestampWithWithDecisecond), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, timestampWithWithDecisecond), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 12:34:56.100'") .roundTripsAs(Types.TIMESTAMP, timestampWithWithDecisecond); - assertBind((ps, i) -> ps.setObject(i, timestampWithWithDecisecond, Types.TIMESTAMP), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, timestampWithWithDecisecond, Types.TIMESTAMP), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 12:34:56.100'") .roundTripsAs(Types.TIMESTAMP, timestampWithWithDecisecond); Timestamp timestampWithMillisecond = new Timestamp(sqlTimestamp.getTime() + 123); - assertBind((ps, i) -> ps.setTimestamp(i, timestampWithMillisecond), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setTimestamp(i, timestampWithMillisecond), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 12:34:56.123'") .roundTripsAs(Types.TIMESTAMP, timestampWithMillisecond); - assertBind((ps, i) -> ps.setObject(i, timestampWithMillisecond), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, timestampWithMillisecond), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 12:34:56.123'") .roundTripsAs(Types.TIMESTAMP, timestampWithMillisecond); - assertBind((ps, i) -> ps.setObject(i, timestampWithMillisecond, Types.TIMESTAMP), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, timestampWithMillisecond, Types.TIMESTAMP), explicitPrepare) .resultsIn("timestamp(3)", "TIMESTAMP '2001-05-06 12:34:56.123'") .roundTripsAs(Types.TIMESTAMP, timestampWithMillisecond); } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testConvertTimestampWithTimeZone(boolean useLegacyPreparedStatements) + @Test + public void testConvertTimestampWithTimeZone() + throws SQLException + { + testConvertTimestampWithTimeZone(true); + testConvertTimestampWithTimeZone(false); + } + + private void testConvertTimestampWithTimeZone(boolean explicitPrepare) throws SQLException { // TODO (https://github.com/trinodb/trino/issues/6299) support ZonedDateTime // String as TIMESTAMP WITH TIME ZONE - assertBind((ps, i) -> ps.setObject(i, "1970-01-01 12:34:56.123 +05:45", Types.TIMESTAMP_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "1970-01-01 12:34:56.123 +05:45", Types.TIMESTAMP_WITH_TIMEZONE), explicitPrepare) .resultsIn("timestamp(3) with time zone", "TIMESTAMP '1970-01-01 12:34:56.123 +05:45'"); - assertBind((ps, i) -> ps.setObject(i, "1970-01-01 12:34:56.123456 +05:45", Types.TIMESTAMP_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "1970-01-01 12:34:56.123456 +05:45", Types.TIMESTAMP_WITH_TIMEZONE), explicitPrepare) .resultsIn("timestamp(6) with time zone", "TIMESTAMP '1970-01-01 12:34:56.123456 +05:45'"); - assertBind((ps, i) -> ps.setObject(i, "1970-01-01 12:34:56.123456789 +05:45", Types.TIMESTAMP_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "1970-01-01 12:34:56.123456789 +05:45", Types.TIMESTAMP_WITH_TIMEZONE), explicitPrepare) .resultsIn("timestamp(9) with time zone", "TIMESTAMP '1970-01-01 12:34:56.123456789 +05:45'"); - assertBind((ps, i) -> ps.setObject(i, "1970-01-01 12:34:56.123456789012 +05:45", Types.TIMESTAMP_WITH_TIMEZONE), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "1970-01-01 12:34:56.123456789012 +05:45", Types.TIMESTAMP_WITH_TIMEZONE), explicitPrepare) .resultsIn("timestamp(12) with time zone", "TIMESTAMP '1970-01-01 12:34:56.123456789012 +05:45'"); } - @Test(dataProvider = "legacyPreparedStatementProvider") - public void testInvalidConversions(boolean useLegacyPreparedStatements) + @Test + public void testInvalidConversions() + throws SQLException + { + testInvalidConversions(true); + testInvalidConversions(false); + } + + private void testInvalidConversions(boolean explicitPrepare) throws SQLException { - assertBind((ps, i) -> ps.setObject(i, String.class), useLegacyPreparedStatements).isInvalid("Unsupported object type: java.lang.Class"); - assertBind((ps, i) -> ps.setObject(i, String.class, Types.BIGINT), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, String.class), explicitPrepare).isInvalid("Unsupported object type: java.lang.Class"); + assertBind((ps, i) -> ps.setObject(i, String.class, Types.BIGINT), explicitPrepare) .isInvalid("Cannot convert instance of java.lang.Class to SQL type " + Types.BIGINT); - assertBind((ps, i) -> ps.setObject(i, "abc", Types.SMALLINT), useLegacyPreparedStatements) + assertBind((ps, i) -> ps.setObject(i, "abc", Types.SMALLINT), explicitPrepare) .isInvalid("Cannot convert instance of java.lang.String to SQL type " + Types.SMALLINT); } @Test - public void testLegacyPreparedStatementsTrue() + public void testExplicitPrepare() throws Exception { - testLegacyPreparedStatementsSetting(true, + testExplicitPrepareSetting(true, "EXECUTE %statement% USING %values%"); } @Test - public void testLegacyPreparedStatementsFalse() + public void testExecuteImmediate() throws Exception { - testLegacyPreparedStatementsSetting(false, + testExplicitPrepareSetting(false, "EXECUTE IMMEDIATE '%query%' USING %values%"); } - private BindAssertion assertBind(Binder binder, boolean useLegacyPreparedStatements) + private BindAssertion assertBind(Binder binder, boolean explicitPrepare) { - return new BindAssertion(() -> this.createConnection(useLegacyPreparedStatements), binder); + return new BindAssertion(() -> this.createConnection(explicitPrepare), binder); } - private Connection createConnection(boolean useLegacyPreparedStatements) + private Connection createConnection(boolean explicitPrepare) throws SQLException { - String url = format("jdbc:trino://%s?legacyPreparedStatements=" + useLegacyPreparedStatements, server.getAddress()); + String url = format("jdbc:trino://%s?explicitPrepare=" + explicitPrepare, server.getAddress()); return DriverManager.getConnection(url, "test", null); } - private Connection createConnection(String catalog, String schema, boolean useLegacyPreparedStatements) + private Connection createConnection(String catalog, String schema, boolean explicitPrepare) throws SQLException { - String url = format("jdbc:trino://%s/%s/%s?legacyPreparedStatements=" + useLegacyPreparedStatements, server.getAddress(), catalog, schema); + String url = format("jdbc:trino://%s/%s/%s?explicitPrepare=" + explicitPrepare, server.getAddress(), catalog, schema); return DriverManager.getConnection(url, "test", null); } - private void testLegacyPreparedStatementsSetting(boolean legacyPreparedStatements, String expectedSql) + private void testExplicitPrepareSetting(boolean explicitPrepare, String expectedSql) throws Exception { String selectSql = "SELECT * FROM blackhole.blackhole.test_table WHERE x = ? AND y = ? AND y <> 'Test'"; String insertSql = "INSERT INTO blackhole.blackhole.test_table (x, y) VALUES (?, ?)"; - try (Connection connection = createConnection(legacyPreparedStatements)) { + try (Connection connection = createConnection(explicitPrepare)) { try (Statement statement = connection.createStatement()) { assertEquals(statement.executeUpdate("CREATE TABLE blackhole.blackhole.test_table (x bigint, y varchar)"), 0); } diff --git a/docs/src/main/sphinx/client/jdbc.md b/docs/src/main/sphinx/client/jdbc.md index c0b55960a81e..cf974490f9cb 100644 --- a/docs/src/main/sphinx/client/jdbc.md +++ b/docs/src/main/sphinx/client/jdbc.md @@ -246,7 +246,7 @@ may not be specified using both methods. - Sets the time zone for the session using the [time zone passed](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/ZoneId.html#of(java.lang.String)). Defaults to the timezone of the JVM running the JDBC driver. -* - `legacyPreparedStatements` +* - `explicitPrepare` - Defaults to `true`. When set to `false`, prepared statements are executed calling a single `EXECUTE IMMEDIATE` query instead of the standard `PREPARE ` followed by `EXECUTE `. This reduces