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 b1522a949a9 Reject additional closed JDBC entry points
b1522a949a9 is described below
commit b1522a949a9df9236b755869de0bf6e86b0ec578
Author: Caideyipi <[email protected]>
AuthorDate: Tue Jun 9 18:13:13 2026 +0800
Reject additional closed JDBC entry points
---
.../iotdb/jdbc/IoTDBAbstractDatabaseMetadata.java | 11 ++++++++-
.../org/apache/iotdb/jdbc/IoTDBConnection.java | 19 +++++++++++++++
.../apache/iotdb/jdbc/IoTDBDatabaseMetadata.java | 4 ++++
.../org/apache/iotdb/jdbc/IoTDBConnectionTest.java | 27 ++++++++++++++++++++++
.../iotdb/jdbc/IoTDBDatabaseMetadataTest.java | 18 ++++++++++++++-
5 files changed, 77 insertions(+), 2 deletions(-)
diff --git
a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBAbstractDatabaseMetadata.java
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBAbstractDatabaseMetadata.java
index b40d7dd2556..40144e33881 100644
---
a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBAbstractDatabaseMetadata.java
+++
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBAbstractDatabaseMetadata.java
@@ -539,17 +539,20 @@ public abstract class IoTDBAbstractDatabaseMetadata
implements DatabaseMetaData
@Override
public String getURL() throws SQLException {
+ checkConnectionOpen();
// TODO: Return the URL for this DBMS or null if it cannot be generated
return this.connection.getUrl();
}
@Override
public String getUserName() throws SQLException {
+ checkConnectionOpen();
return connection.getUserName();
}
@Override
public boolean isReadOnly() throws SQLException {
+ checkConnectionOpen();
try {
return client.getProperties().isReadOnly;
} catch (TException e) {
@@ -585,6 +588,7 @@ public abstract class IoTDBAbstractDatabaseMetadata
implements DatabaseMetaData
@Override
public String getDatabaseProductVersion() throws SQLException {
+ checkConnectionOpen();
String serverVersion = "";
String sql = "SHOW VERSION";
try (Statement stmt = this.connection.createStatement();
@@ -681,6 +685,7 @@ public abstract class IoTDBAbstractDatabaseMetadata
implements DatabaseMetaData
@Override
public String getSystemFunctions() throws SQLException {
+ checkConnectionOpen();
String result = "";
Statement statement = null;
ResultSet resultSet = null;
@@ -1037,6 +1042,7 @@ public abstract class IoTDBAbstractDatabaseMetadata
implements DatabaseMetaData
@Override
public int getMaxConnections() throws SQLException {
+ checkConnectionOpen();
int maxcount = 0;
try {
maxcount = client.getProperties().getMaxConcurrentClientNum();
@@ -1083,6 +1089,7 @@ public abstract class IoTDBAbstractDatabaseMetadata
implements DatabaseMetaData
@Override
public int getMaxStatementLength() throws SQLException {
+ checkConnectionOpen();
try {
return client.getProperties().getThriftMaxFrameSize();
} catch (TException e) {
@@ -2463,6 +2470,7 @@ public abstract class IoTDBAbstractDatabaseMetadata
implements DatabaseMetaData
@Override
public int getDatabaseMajorVersion() throws SQLException {
+ checkConnectionOpen();
int majorVersion = 0;
try {
String version = client.getProperties().getVersion();
@@ -2478,6 +2486,7 @@ public abstract class IoTDBAbstractDatabaseMetadata
implements DatabaseMetaData
@Override
public int getDatabaseMinorVersion() throws SQLException {
+ checkConnectionOpen();
int minorVersion = 0;
try {
String version = client.getProperties().getVersion();
@@ -2869,7 +2878,7 @@ public abstract class IoTDBAbstractDatabaseMetadata
implements DatabaseMetaData
return JdbcWrapperUtils.isWrapperFor(this, arg0);
}
- private void checkConnectionOpen() throws SQLException {
+ protected final void checkConnectionOpen() throws SQLException {
if (connection == null || connection.isClosed()) {
throw new SQLException(
String.format(JdbcMessages.CANNOT_AFTER_CONNECTION_CLOSED, "get
metadata"));
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 58e155ef432..f514719fced 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
@@ -560,6 +560,7 @@ public class IoTDBConnection implements Connection {
}
public void setQueryTimeout(int seconds) throws SQLException {
+ checkOpen("setQueryTimeout");
if (seconds < 0) {
throw new SQLException(
String.format(JdbcMessages.QUERY_TIMEOUT_MUST_BE_NON_NEGATIVE,
seconds));
@@ -690,6 +691,9 @@ public class IoTDBConnection implements Connection {
}
public boolean reconnect() {
+ if (isClosed) {
+ return false;
+ }
boolean flag = false;
for (int i = 1; i <= Config.RETRY_NUM; i++) {
try {
@@ -722,6 +726,7 @@ public class IoTDBConnection implements Connection {
}
public void setTimeZone(String timeZone) throws TException,
IoTDBSQLException {
+ checkOpenForIoTDBException("setTimeZone");
ZoneId newZoneId = parseTimeZone(timeZone);
TSSetTimeZoneReq req = new TSSetTimeZoneReq(sessionId, timeZone);
TSStatus resp = getClient().setTimeZone(req);
@@ -745,6 +750,7 @@ public class IoTDBConnection implements Connection {
}
public ServerProperties getServerProperties() throws TException {
+ checkOpenForTException("getServerProperties");
return getClient().getProperties();
}
@@ -779,4 +785,17 @@ public class IoTDBConnection implements Connection {
String.format(JdbcMessages.CANNOT_AFTER_CONNECTION_CLOSED, action),
null);
}
}
+
+ private void checkOpenForIoTDBException(String action) throws
IoTDBSQLException {
+ if (isClosed) {
+ throw new IoTDBSQLException(
+ String.format(JdbcMessages.CANNOT_AFTER_CONNECTION_CLOSED, action));
+ }
+ }
+
+ private void checkOpenForTException(String action) throws TException {
+ if (isClosed) {
+ throw new
TException(String.format(JdbcMessages.CANNOT_AFTER_CONNECTION_CLOSED, action));
+ }
+ }
}
diff --git
a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
index 2f4ea5af240..add855fb4f8 100644
---
a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
+++
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadata.java
@@ -663,9 +663,12 @@ public class IoTDBDatabaseMetadata extends
IoTDBAbstractDatabaseMetadata {
@Override
public String toString() {
try {
+ checkConnectionOpen();
return getMetadataInJsonFunc();
} catch (IoTDBSQLException e) {
LOGGER.error(JdbcMessages.FAILED_TO_FETCH_METADATA_JSON, e);
+ } catch (SQLException e) {
+ LOGGER.error(JdbcMessages.FAILED_TO_FETCH_METADATA_JSON, e);
} catch (TException e) {
boolean flag = connection.reconnect();
this.client = connection.getClient();
@@ -694,6 +697,7 @@ public class IoTDBDatabaseMetadata extends
IoTDBAbstractDatabaseMetadata {
* recommend using getMetadataInJson() instead of toString()
*/
public String getMetadataInJson() throws SQLException {
+ checkConnectionOpen();
try {
return getMetadataInJsonFunc();
} catch (TException e) {
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 77fde2f6151..6ec7f2c27c5 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
@@ -27,6 +27,7 @@ import org.apache.iotdb.service.rpc.thrift.TSGetTimeZoneResp;
import org.apache.iotdb.service.rpc.thrift.TSSetTimeZoneReq;
import org.apache.thrift.TException;
+import org.apache.thrift.transport.TTransport;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -74,6 +75,7 @@ public class IoTDBConnectionTest {
@Test
public void testSetTimeZone() throws IoTDBSQLException, TException {
+ openConnection(connection);
String timeZone = "Asia/Shanghai";
when(client.setTimeZone(any(TSSetTimeZoneReq.class))).thenReturn(new
TSStatus(successStatus));
connection.setClient(client);
@@ -103,6 +105,7 @@ public class IoTDBConnectionTest {
@Test
public void testSetTimeZoneRejectsInvalidZoneBeforeRpc() throws TException {
+ openConnection(connection);
connection.setClient(client);
assertThrows(IoTDBSQLException.class, () ->
connection.setTimeZone("invalid-zone"));
@@ -143,6 +146,7 @@ public class IoTDBConnectionTest {
@Test
public void testGetServerProperties() throws TException {
+ openConnection(connection);
final String version = "v0.1";
@SuppressWarnings("serial")
final List<String> supportedAggregationTime =
@@ -168,6 +172,7 @@ public class IoTDBConnectionTest {
@Test
public void setTimeoutTest() throws SQLException {
+ openConnection(connection);
connection.setQueryTimeout(60);
Assert.assertEquals(60, connection.getQueryTimeout());
}
@@ -303,8 +308,20 @@ public class IoTDBConnectionTest {
assertThrows(SQLException.class, () -> connection.rollback());
assertThrows(SQLException.class, () -> connection.rollback((Savepoint)
null));
assertThrows(SQLException.class, () -> connection.setNetworkTimeout(null,
0));
+ assertThrows(SQLException.class, () -> connection.setQueryTimeout(60));
assertThrows(SQLException.class, () -> connection.setSavepoint());
assertThrows(SQLException.class, () -> connection.setSavepoint("s"));
+ assertThrows(IoTDBSQLException.class, () ->
connection.setTimeZone("+07:00"));
+ assertThrows(TException.class, () -> connection.getServerProperties());
+ }
+
+ @Test
+ public void testClosedConnectionDoesNotReconnect() {
+ TTransport transport = org.mockito.Mockito.mock(TTransport.class);
+ setTransport(connection, transport);
+
+ assertFalse(connection.reconnect());
+ verify(transport, never()).close();
}
private void openConnection(IoTDBConnection target) {
@@ -316,4 +333,14 @@ public class IoTDBConnectionTest {
throw new AssertionError(e);
}
}
+
+ private void setTransport(IoTDBConnection target, TTransport transport) {
+ try {
+ Field transportField =
IoTDBConnection.class.getDeclaredField("transport");
+ transportField.setAccessible(true);
+ transportField.set(target, transport);
+ } catch (ReflectiveOperationException e) {
+ throw new AssertionError(e);
+ }
+ }
}
diff --git
a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadataTest.java
b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadataTest.java
index 8332485d6cd..f4dc8564a20 100644
---
a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadataTest.java
+++
b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBDatabaseMetadataTest.java
@@ -27,6 +27,7 @@ import org.apache.iotdb.service.rpc.thrift.ServerProperties;
import org.apache.iotdb.service.rpc.thrift.TSExecuteBatchStatementReq;
import org.apache.iotdb.service.rpc.thrift.TSExecuteStatementReq;
import org.apache.iotdb.service.rpc.thrift.TSExecuteStatementResp;
+import org.apache.iotdb.service.rpc.thrift.TSFetchMetadataReq;
import org.apache.thrift.TException;
import org.junit.Assert;
@@ -53,6 +54,8 @@ import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class IoTDBDatabaseMetadataTest {
@@ -106,12 +109,25 @@ public class IoTDBDatabaseMetadataTest {
}
@Test
- public void testClosedConnectionRejectsMetadataWrapperMethods() throws
SQLException {
+ public void testClosedConnectionRejectsMetadataOperations() throws
SQLException, TException {
when(connection.isClosed()).thenReturn(true);
assertThrows(SQLException.class, () ->
databaseMetaData.isWrapperFor(DatabaseMetaData.class));
assertThrows(SQLException.class, () ->
databaseMetaData.unwrap(DatabaseMetaData.class));
assertThrows(SQLException.class, () -> databaseMetaData.getConnection());
+ assertThrows(SQLException.class, () -> databaseMetaData.getURL());
+ assertThrows(SQLException.class, () -> databaseMetaData.getUserName());
+ assertThrows(SQLException.class, () -> databaseMetaData.isReadOnly());
+ assertThrows(SQLException.class, () ->
databaseMetaData.getDatabaseProductVersion());
+ assertThrows(SQLException.class, () ->
databaseMetaData.getSystemFunctions());
+ assertThrows(SQLException.class, () ->
databaseMetaData.getMaxConnections());
+ assertThrows(SQLException.class, () ->
databaseMetaData.getMaxStatementLength());
+ assertThrows(SQLException.class, () ->
databaseMetaData.getDatabaseMajorVersion());
+ assertThrows(SQLException.class, () ->
databaseMetaData.getDatabaseMinorVersion());
+ assertThrows(
+ SQLException.class, () -> ((IoTDBDatabaseMetadata)
databaseMetaData).getMetadataInJson());
+ assertEquals("", databaseMetaData.toString());
+ verify(client, never()).fetchMetadata(any(TSFetchMetadataReq.class));
}
@Test