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

Reply via email to