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 871a9955e76 Reject more closed JDBC connection entry points
871a9955e76 is described below

commit 871a9955e764678c0e3491a867cb5f917deba06c
Author: Caideyipi <[email protected]>
AuthorDate: Tue Jun 9 16:52:54 2026 +0800

    Reject more closed JDBC connection entry points
---
 .../iotdb/jdbc/IoTDBAbstractDatabaseMetadata.java  | 10 ++++
 .../org/apache/iotdb/jdbc/IoTDBConnection.java     | 27 ++++++++++
 .../org/apache/iotdb/jdbc/IoTDBConnectionTest.java | 59 ++++++++++++++++++++++
 .../iotdb/jdbc/IoTDBDatabaseMetadataTest.java      | 10 ++++
 4 files changed, 106 insertions(+)

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 5ffaea704c9..b40d7dd2556 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
@@ -2284,6 +2284,7 @@ public abstract class IoTDBAbstractDatabaseMetadata 
implements DatabaseMetaData
 
   @Override
   public Connection getConnection() throws SQLException {
+    checkConnectionOpen();
     return connection;
   }
 
@@ -2858,11 +2859,20 @@ public abstract class IoTDBAbstractDatabaseMetadata 
implements DatabaseMetaData
 
   @Override
   public <T> T unwrap(Class<T> arg0) throws SQLException {
+    checkConnectionOpen();
     return JdbcWrapperUtils.unwrap(this, arg0);
   }
 
   @Override
   public boolean isWrapperFor(Class<?> arg0) throws SQLException {
+    checkConnectionOpen();
     return JdbcWrapperUtils.isWrapperFor(this, arg0);
   }
+
+  private 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 f41eec12cc2..25a141e73c6 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
@@ -166,6 +166,7 @@ public class IoTDBConnection implements Connection {
 
   @Override
   public void abort(Executor arg0) throws SQLException {
+    checkOpen("abort");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_ABORT);
   }
 
@@ -201,26 +202,31 @@ public class IoTDBConnection implements Connection {
 
   @Override
   public Array createArrayOf(String arg0, Object[] arg1) throws SQLException {
+    checkOpen("createArrayOf");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_CREATE_ARRAY_OF);
   }
 
   @Override
   public Blob createBlob() throws SQLException {
+    checkOpen("createBlob");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_CREATE_BLOB);
   }
 
   @Override
   public Clob createClob() throws SQLException {
+    checkOpen("createClob");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_CREATE_CLOB);
   }
 
   @Override
   public NClob createNClob() throws SQLException {
+    checkOpen("createNClob");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_CREATE_NCLOB);
   }
 
   @Override
   public SQLXML createSQLXML() throws SQLException {
+    checkOpen("createSQLXML");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_CREATE_SQLXML);
   }
 
@@ -248,11 +254,13 @@ public class IoTDBConnection implements Connection {
 
   @Override
   public Statement createStatement(int arg0, int arg1, int arg2) throws 
SQLException {
+    checkOpen("createStatement");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_CREATE_STATEMENT);
   }
 
   @Override
   public Struct createStruct(String arg0, Object[] arg1) throws SQLException {
+    checkOpen("createStruct");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_CREATE_STRUCT);
   }
 
@@ -304,6 +312,7 @@ public class IoTDBConnection implements Connection {
 
   @Override
   public Properties getClientInfo() throws SQLException {
+    checkOpen("getClientInfo");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_GET_CLIENT_INFO);
   }
 
@@ -314,6 +323,7 @@ public class IoTDBConnection implements Connection {
 
   @Override
   public String getClientInfo(String arg0) throws SQLException {
+    checkOpen("getClientInfo");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_GET_CLIENT_INFO);
   }
 
@@ -325,6 +335,7 @@ public class IoTDBConnection implements Connection {
 
   @Override
   public void setHoldability(int arg0) throws SQLException {
+    checkOpen("setHoldability");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_SET_HOLDABILITY);
   }
 
@@ -386,16 +397,19 @@ public class IoTDBConnection implements Connection {
 
   @Override
   public void setTransactionIsolation(int arg0) throws SQLException {
+    checkOpen("setTransactionIsolation");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_SET_TRANSACTION_ISOLATION);
   }
 
   @Override
   public Map<String, Class<?>> getTypeMap() throws SQLException {
+    checkOpen("getTypeMap");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_GET_TYPE_MAP);
   }
 
   @Override
   public void setTypeMap(Map<String, Class<?>> arg0) throws SQLException {
+    checkOpen("setTypeMap");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_SET_TYPE_MAP);
   }
 
@@ -434,22 +448,26 @@ public class IoTDBConnection implements Connection {
 
   @Override
   public String nativeSQL(String arg0) throws SQLException {
+    checkOpen("nativeSQL");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_NATIVE_SQL);
   }
 
   @Override
   public CallableStatement prepareCall(String arg0) throws SQLException {
+    checkOpen("prepareCall");
     throw new SQLException(NOT_SUPPORT_PREPARE_CALL);
   }
 
   @Override
   public CallableStatement prepareCall(String arg0, int arg1, int arg2) throws 
SQLException {
+    checkOpen("prepareCall");
     throw new SQLException(NOT_SUPPORT_PREPARE_CALL);
   }
 
   @Override
   public CallableStatement prepareCall(String arg0, int arg1, int arg2, int 
arg3)
       throws SQLException {
+    checkOpen("prepareCall");
     throw new SQLException(NOT_SUPPORT_PREPARE_CALL);
   }
 
@@ -465,22 +483,26 @@ public class IoTDBConnection implements Connection {
 
   @Override
   public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) 
throws SQLException {
+    checkOpen("prepareStatement");
     throw new SQLException(NOT_SUPPORT_PREPARE_STATEMENT);
   }
 
   @Override
   public PreparedStatement prepareStatement(String sql, int[] columnIndexes) 
throws SQLException {
+    checkOpen("prepareStatement");
     throw new SQLException(NOT_SUPPORT_PREPARE_STATEMENT);
   }
 
   @Override
   public PreparedStatement prepareStatement(String sql, String[] columnNames) 
throws SQLException {
+    checkOpen("prepareStatement");
     throw new SQLException(NOT_SUPPORT_PREPARE_STATEMENT);
   }
 
   @Override
   public PreparedStatement prepareStatement(String sql, int resultSetType, int 
resultSetConcurrency)
       throws SQLException {
+    checkOpen("prepareStatement");
     throw new SQLException(NOT_SUPPORT_PREPARE_STATEMENT);
   }
 
@@ -488,11 +510,13 @@ public class IoTDBConnection implements Connection {
   public PreparedStatement prepareStatement(
       String sql, int resultSetType, int resultSetConcurrency, int 
resultSetHoldability)
       throws SQLException {
+    checkOpen("prepareStatement");
     throw new SQLException(NOT_SUPPORT_PREPARE_STATEMENT);
   }
 
   @Override
   public void releaseSavepoint(Savepoint arg0) throws SQLException {
+    checkOpen("releaseSavepoint");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_RELEASE_SAVEPOINT);
   }
 
@@ -525,6 +549,7 @@ public class IoTDBConnection implements Connection {
 
   @Override
   public void setNetworkTimeout(Executor arg0, int arg1) throws SQLException {
+    checkOpen("setNetworkTimeout");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_SET_NETWORK_TIMEOUT);
   }
 
@@ -542,11 +567,13 @@ public class IoTDBConnection implements Connection {
 
   @Override
   public Savepoint setSavepoint() throws SQLException {
+    checkOpen("setSavepoint");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_SET_SAVEPOINT);
   }
 
   @Override
   public Savepoint setSavepoint(String arg0) throws SQLException {
+    checkOpen("setSavepoint");
     throw new SQLException(JdbcMessages.NOT_SUPPORT_SET_SAVEPOINT);
   }
 
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 8e0a77ded50..f0d55e1a51d 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
@@ -39,6 +39,7 @@ import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLClientInfoException;
 import java.sql.SQLException;
+import java.sql.Savepoint;
 import java.time.ZoneId;
 import java.util.ArrayList;
 import java.util.List;
@@ -213,27 +214,85 @@ public class IoTDBConnectionTest {
 
     assertThrows(SQLException.class, () -> 
connection.isWrapperFor(Connection.class));
     assertThrows(SQLException.class, () -> 
connection.unwrap(Connection.class));
+    assertThrows(SQLException.class, () -> connection.abort(null));
     assertThrows(SQLException.class, () -> connection.clearWarnings());
     assertThrows(SQLException.class, () -> connection.commit());
+    assertThrows(SQLException.class, () -> connection.createArrayOf("TEXT", 
new Object[0]));
+    assertThrows(SQLException.class, () -> connection.createBlob());
+    assertThrows(SQLException.class, () -> connection.createClob());
+    assertThrows(SQLException.class, () -> connection.createNClob());
+    assertThrows(SQLException.class, () -> connection.createSQLXML());
     assertThrows(SQLException.class, () -> connection.createStatement());
     assertThrows(
         SQLException.class,
         () -> connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, 
ResultSet.CONCUR_READ_ONLY));
+    assertThrows(
+        SQLException.class,
+        () ->
+            connection.createStatement(
+                ResultSet.TYPE_FORWARD_ONLY,
+                ResultSet.CONCUR_READ_ONLY,
+                ResultSet.HOLD_CURSORS_OVER_COMMIT));
+    assertThrows(SQLException.class, () -> connection.createStruct("TEXT", new 
Object[0]));
     assertThrows(SQLException.class, () -> connection.prepareStatement("SELECT 
?"));
+    assertThrows(SQLException.class, () -> connection.prepareStatement("SELECT 
?", 0));
+    assertThrows(SQLException.class, () -> connection.prepareStatement("SELECT 
?", new int[0]));
+    assertThrows(SQLException.class, () -> connection.prepareStatement("SELECT 
?", new String[0]));
+    assertThrows(
+        SQLException.class,
+        () ->
+            connection.prepareStatement(
+                "SELECT ?", ResultSet.TYPE_FORWARD_ONLY, 
ResultSet.CONCUR_READ_ONLY));
+    assertThrows(
+        SQLException.class,
+        () ->
+            connection.prepareStatement(
+                "SELECT ?",
+                ResultSet.TYPE_FORWARD_ONLY,
+                ResultSet.CONCUR_READ_ONLY,
+                ResultSet.HOLD_CURSORS_OVER_COMMIT));
+    assertThrows(SQLException.class, () -> connection.prepareCall("CALL x"));
+    assertThrows(
+        SQLException.class,
+        () ->
+            connection.prepareCall(
+                "CALL x", ResultSet.TYPE_FORWARD_ONLY, 
ResultSet.CONCUR_READ_ONLY));
+    assertThrows(
+        SQLException.class,
+        () ->
+            connection.prepareCall(
+                "CALL x",
+                ResultSet.TYPE_FORWARD_ONLY,
+                ResultSet.CONCUR_READ_ONLY,
+                ResultSet.HOLD_CURSORS_OVER_COMMIT));
     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.getClientInfo());
+    assertThrows(SQLException.class, () -> 
connection.getClientInfo("time_zone"));
     assertThrows(SQLException.class, () -> connection.getHoldability());
+    assertThrows(
+        SQLException.class, () -> 
connection.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT));
     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.setTransactionIsolation(Connection.TRANSACTION_NONE));
+    assertThrows(SQLException.class, () -> connection.getTypeMap());
+    assertThrows(SQLException.class, () -> connection.setTypeMap(null));
     assertThrows(SQLException.class, () -> connection.getWarnings());
     assertThrows(SQLException.class, () -> connection.isReadOnly());
     assertThrows(SQLException.class, () -> connection.setReadOnly(false));
+    assertThrows(SQLException.class, () -> connection.nativeSQL("SELECT 1"));
+    assertThrows(SQLException.class, () -> connection.releaseSavepoint(null));
     assertThrows(SQLException.class, () -> connection.rollback());
+    assertThrows(SQLException.class, () -> connection.rollback((Savepoint) 
null));
+    assertThrows(SQLException.class, () -> connection.setNetworkTimeout(null, 
0));
+    assertThrows(SQLException.class, () -> connection.setSavepoint());
+    assertThrows(SQLException.class, () -> connection.setSavepoint("s"));
   }
 
   private void openConnection(IoTDBConnection target) {
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 804f3f89d6b..8332485d6cd 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
@@ -50,6 +50,7 @@ import java.util.Map;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 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.when;
@@ -104,6 +105,15 @@ public class IoTDBDatabaseMetadataTest {
     databaseMetaData.unwrap(String.class);
   }
 
+  @Test
+  public void testClosedConnectionRejectsMetadataWrapperMethods() throws 
SQLException {
+    when(connection.isClosed()).thenReturn(true);
+
+    assertThrows(SQLException.class, () -> 
databaseMetaData.isWrapperFor(DatabaseMetaData.class));
+    assertThrows(SQLException.class, () -> 
databaseMetaData.unwrap(DatabaseMetaData.class));
+    assertThrows(SQLException.class, () -> databaseMetaData.getConnection());
+  }
+
   @Test
   public void testGetBestRowIdentifier() throws SQLException {
     ResultSet resultSet = databaseMetaData.getBestRowIdentifier(null, null, 
null, 0, true);

Reply via email to