This is an automated email from the ASF dual-hosted git repository.
Caideyipi pushed a commit to branch codex/jdbc-driver-info
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/codex/jdbc-driver-info by this
push:
new 30ca82e7b4a Reject closed JDBC connection operations
30ca82e7b4a is described below
commit 30ca82e7b4a2d367af9204070d2bba368f2873b3
Author: Caideyipi <[email protected]>
AuthorDate: Tue Jun 9 16:40:14 2026 +0800
Reject closed JDBC connection operations
---
.../org/apache/iotdb/jdbc/IoTDBConnection.java | 63 +++++++++++++++-------
.../org/apache/iotdb/jdbc/IoTDBConnectionTest.java | 63 ++++++++++++++++++++--
2 files changed, 102 insertions(+), 24 deletions(-)
diff --git
a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
index 2a9cd3816df..f41eec12cc2 100644
--- a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
+++ b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBConnection.java
@@ -154,11 +154,13 @@ public class IoTDBConnection implements Connection {
@Override
public boolean isWrapperFor(Class<?> arg0) throws SQLException {
+ checkOpen("isWrapperFor");
return JdbcWrapperUtils.isWrapperFor(this, arg0);
}
@Override
public <T> T unwrap(Class<T> arg0) throws SQLException {
+ checkOpen("unwrap");
return JdbcWrapperUtils.unwrap(this, arg0);
}
@@ -168,7 +170,8 @@ public class IoTDBConnection implements Connection {
}
@Override
- public void clearWarnings() {
+ public void clearWarnings() throws SQLException {
+ checkOpen("clearWarnings");
warningChain = null;
}
@@ -192,7 +195,9 @@ public class IoTDBConnection implements Connection {
}
@Override
- public void commit() throws SQLException {}
+ public void commit() throws SQLException {
+ checkOpen("commit");
+ }
@Override
public Array createArrayOf(String arg0, Object[] arg1) throws SQLException {
@@ -221,15 +226,14 @@ public class IoTDBConnection implements Connection {
@Override
public Statement createStatement() throws SQLException {
- if (isClosed) {
- throw new SQLException(JdbcMessages.CANNOT_CREATE_STATEMENT_CLOSED);
- }
+ checkOpen("createStatement");
return new IoTDBStatement(this, getClient(), sessionId, zoneId, charset,
queryTimeout);
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency)
throws SQLException {
+ checkOpen("createStatement");
if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY) {
throw new SQLException(
String.format(
@@ -253,22 +257,26 @@ public class IoTDBConnection implements Connection {
}
@Override
- public boolean getAutoCommit() {
+ public boolean getAutoCommit() throws SQLException {
+ checkOpen("getAutoCommit");
return autoCommit;
}
@Override
- public void setAutoCommit(boolean arg0) {
+ public void setAutoCommit(boolean arg0) throws SQLException {
+ checkOpen("setAutoCommit");
autoCommit = arg0;
}
@Override
- public String getCatalog() {
+ public String getCatalog() throws SQLException {
+ checkOpen("getCatalog");
return APACHE_IOTDB;
}
@Override
public void setCatalog(String arg0) throws SQLException {
+ checkOpen("setCatalog");
if (getSqlDialect().equals(Constant.TABLE_DIALECT)) {
if (arg0 == null) {
throw new SQLException("catalog cannot be null");
@@ -310,7 +318,8 @@ public class IoTDBConnection implements Connection {
}
@Override
- public int getHoldability() {
+ public int getHoldability() throws SQLException {
+ checkOpen("getHoldability");
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
}
@@ -321,9 +330,7 @@ public class IoTDBConnection implements Connection {
@Override
public DatabaseMetaData getMetaData() throws SQLException {
- if (isClosed) {
- throw new SQLException(JdbcMessages.CANNOT_CREATE_STATEMENT_CLOSED);
- }
+ checkOpen("getMetaData");
if (getSqlDialect().equals(Constant.TABLE_DIALECT)) {
return new IoTDBRelationalDatabaseMetadata(this, getClient(), sessionId,
zoneId);
}
@@ -331,12 +338,14 @@ public class IoTDBConnection implements Connection {
}
@Override
- public int getNetworkTimeout() {
+ public int getNetworkTimeout() throws SQLException {
+ checkOpen("getNetworkTimeout");
return networkTimeout;
}
@Override
public String getSchema() throws SQLException {
+ checkOpen("getSchema");
if (getSqlDialect().equals(Constant.TABLE_DIALECT)) {
return getDatabase();
}
@@ -345,6 +354,7 @@ public class IoTDBConnection implements Connection {
@Override
public void setSchema(String arg0) throws SQLException {
+ checkOpen("setSchema");
// changeDefaultDatabase(arg0);
if (getSqlDialect().equals(Constant.TABLE_DIALECT)) {
if (arg0 == null) {
@@ -369,7 +379,8 @@ public class IoTDBConnection implements Connection {
}
@Override
- public int getTransactionIsolation() {
+ public int getTransactionIsolation() throws SQLException {
+ checkOpen("getTransactionIsolation");
return Connection.TRANSACTION_NONE;
}
@@ -389,7 +400,8 @@ public class IoTDBConnection implements Connection {
}
@Override
- public SQLWarning getWarnings() {
+ public SQLWarning getWarnings() throws SQLException {
+ checkOpen("getWarnings");
return warningChain;
}
@@ -399,12 +411,14 @@ public class IoTDBConnection implements Connection {
}
@Override
- public boolean isReadOnly() {
+ public boolean isReadOnly() throws SQLException {
+ checkOpen("isReadOnly");
return false;
}
@Override
public void setReadOnly(boolean readonly) throws SQLException {
+ checkOpen("setReadOnly");
if (readonly) {
throw new SQLException(JdbcMessages.NOT_SUPPORT_READ_ONLY);
}
@@ -441,6 +455,7 @@ public class IoTDBConnection implements Connection {
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
+ checkOpen("prepareStatement");
if (getSqlDialect().equals(Constant.TABLE_DIALECT)) {
return new IoTDBTablePreparedStatement(this, getClient(), sessionId,
sql, zoneId, charset);
} else {
@@ -482,12 +497,14 @@ public class IoTDBConnection implements Connection {
}
@Override
- public void rollback() {
+ public void rollback() throws SQLException {
+ checkOpen("rollback");
// do nothing in rollback
}
@Override
- public void rollback(Savepoint arg0) {
+ public void rollback(Savepoint arg0) throws SQLException {
+ checkOpen("rollback");
// do nothing in rollback
}
@@ -554,13 +571,13 @@ public class IoTDBConnection implements Connection {
DeepCopyRpcTransportFactory.INSTANCE.getTransport(
params.getHost(),
params.getPort(),
- getNetworkTimeout(),
+ networkTimeout,
params.getTrustStore(),
params.getTrustStorePwd());
} else {
transport =
DeepCopyRpcTransportFactory.INSTANCE.getTransport(
- params.getHost(), params.getPort(), getNetworkTimeout());
+ params.getHost(), params.getPort(), networkTimeout);
}
if (!transport.isOpen()) {
transport.open();
@@ -720,4 +737,10 @@ public class IoTDBConnection implements Connection {
public String getDatabase() {
return params.getDb().orElse(null);
}
+
+ private void checkOpen(String action) throws SQLException {
+ if (isClosed) {
+ throw new
SQLException(String.format(JdbcMessages.CANNOT_AFTER_CONNECTION_CLOSED,
action));
+ }
+ }
}
diff --git
a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBConnectionTest.java
b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBConnectionTest.java
index 2064a4027f6..8e0a77ded50 100644
---
a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBConnectionTest.java
+++
b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBConnectionTest.java
@@ -34,6 +34,7 @@ import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLClientInfoException;
@@ -129,6 +130,7 @@ public class IoTDBConnectionTest {
return Constant.TABLE_DIALECT;
}
};
+ openConnection(tableConnection);
assertThrows(SQLException.class, () -> tableConnection.setCatalog(null));
assertThrows(SQLException.class, () -> tableConnection.setSchema(null));
@@ -166,9 +168,18 @@ public class IoTDBConnectionTest {
}
@Test
- public void testStandardConnectionStateMethods() throws SQLException {
+ public void testStandardConnectionStateMethods() throws Exception {
+ openConnection(connection);
+
+ assertFalse(connection.getAutoCommit());
+ connection.setAutoCommit(true);
+ assertTrue(connection.getAutoCommit());
+ assertEquals("Apache IoTDB", connection.getCatalog());
assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT,
connection.getHoldability());
- assertFalse(connection.isValid(0));
+ assertEquals(Connection.TRANSACTION_NONE,
connection.getTransactionIsolation());
+ assertFalse(connection.isReadOnly());
+ connection.setReadOnly(false);
+ assertTrue(connection.isValid(0));
}
@Test(expected = SQLException.class)
@@ -177,7 +188,9 @@ public class IoTDBConnectionTest {
}
@Test
- public void testWrapperMethods() throws SQLException {
+ public void testWrapperMethods() throws Exception {
+ openConnection(connection);
+
assertTrue(connection.isWrapperFor(IoTDBConnection.class));
assertTrue(connection.isWrapperFor(Connection.class));
assertFalse(connection.isWrapperFor(String.class));
@@ -187,7 +200,49 @@ public class IoTDBConnectionTest {
}
@Test(expected = SQLException.class)
- public void testUnwrapRejectsUnsupportedClass() throws SQLException {
+ public void testUnwrapRejectsUnsupportedClass() throws Exception {
+ openConnection(connection);
+
connection.unwrap(String.class);
}
+
+ @Test
+ public void testClosedConnectionRejectsOperations() throws SQLException {
+ assertTrue(connection.isClosed());
+ assertFalse(connection.isValid(0));
+
+ assertThrows(SQLException.class, () ->
connection.isWrapperFor(Connection.class));
+ assertThrows(SQLException.class, () ->
connection.unwrap(Connection.class));
+ assertThrows(SQLException.class, () -> connection.clearWarnings());
+ assertThrows(SQLException.class, () -> connection.commit());
+ assertThrows(SQLException.class, () -> connection.createStatement());
+ assertThrows(
+ SQLException.class,
+ () -> connection.createStatement(ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY));
+ assertThrows(SQLException.class, () -> connection.prepareStatement("SELECT
?"));
+ assertThrows(SQLException.class, () -> connection.getAutoCommit());
+ assertThrows(SQLException.class, () -> connection.setAutoCommit(true));
+ assertThrows(SQLException.class, () -> connection.getCatalog());
+ assertThrows(SQLException.class, () -> connection.setCatalog("root"));
+ assertThrows(SQLException.class, () -> connection.getHoldability());
+ assertThrows(SQLException.class, () -> connection.getMetaData());
+ assertThrows(SQLException.class, () -> connection.getNetworkTimeout());
+ assertThrows(SQLException.class, () -> connection.getSchema());
+ assertThrows(SQLException.class, () -> connection.setSchema("root"));
+ assertThrows(SQLException.class, () ->
connection.getTransactionIsolation());
+ assertThrows(SQLException.class, () -> connection.getWarnings());
+ assertThrows(SQLException.class, () -> connection.isReadOnly());
+ assertThrows(SQLException.class, () -> connection.setReadOnly(false));
+ assertThrows(SQLException.class, () -> connection.rollback());
+ }
+
+ private void openConnection(IoTDBConnection target) {
+ try {
+ Field isClosedField = IoTDBConnection.class.getDeclaredField("isClosed");
+ isClosedField.setAccessible(true);
+ isClosedField.setBoolean(target, false);
+ } catch (ReflectiveOperationException e) {
+ throw new AssertionError(e);
+ }
+ }
}