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 12d609fdf7a Improve JDBC result set edge cases
12d609fdf7a is described below

commit 12d609fdf7a7d5d1f5bad33193065f7d81ac509e
Author: Caideyipi <[email protected]>
AuthorDate: Tue Jun 9 11:57:26 2026 +0800

    Improve JDBC result set edge cases
---
 .../org/apache/iotdb/jdbc/IoTDBJDBCResultSet.java  |  43 +++++---
 .../apache/iotdb/jdbc/IoTDBJDBCResultSetTest.java  | 113 ++++++++++++++-------
 2 files changed, 105 insertions(+), 51 deletions(-)

diff --git 
a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBJDBCResultSet.java 
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBJDBCResultSet.java
index fa615a2f2ab..302d774105d 100644
--- 
a/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBJDBCResultSet.java
+++ 
b/iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBJDBCResultSet.java
@@ -67,8 +67,6 @@ import java.util.Map;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
-import static org.apache.iotdb.rpc.RpcUtils.convertToTimestamp;
-
 public class IoTDBJDBCResultSet implements ResultSet {
 
   public static final String OBJECT_ERR_MSG = "OBJECT Type only support 
getString";
@@ -211,8 +209,8 @@ public class IoTDBJDBCResultSet implements ResultSet {
   }
 
   @Override
-  public void clearWarnings() throws SQLException {
-    throw new SQLException(Constant.METHOD_NOT_SUPPORTED);
+  public void clearWarnings() {
+    warningChain = null;
   }
 
   @Override
@@ -448,7 +446,8 @@ public class IoTDBJDBCResultSet implements ResultSet {
 
   @Override
   public Date getDate(int columnIndex) throws SQLException {
-    return DateUtils.parseIntToDate(getInt(columnIndex));
+    int date = getInt(columnIndex);
+    return wasNull() ? null : DateUtils.parseIntToDate(date);
   }
 
   @Override
@@ -496,18 +495,24 @@ public class IoTDBJDBCResultSet implements ResultSet {
   }
 
   @Override
-  public void setFetchDirection(int arg0) throws SQLException {
-    throw new SQLException(Constant.METHOD_NOT_SUPPORTED);
+  public void setFetchDirection(int direction) throws SQLException {
+    if (direction != ResultSet.FETCH_FORWARD) {
+      throw new 
SQLException(String.format(JdbcMessages.DIRECTION_NOT_SUPPORTED, direction));
+    }
   }
 
   @Override
-  public int getFetchSize() throws SQLException {
-    throw new SQLException(Constant.METHOD_NOT_SUPPORTED);
+  public int getFetchSize() {
+    return ioTDBRpcDataSet.getFetchSize();
   }
 
   @Override
-  public void setFetchSize(int arg0) throws SQLException {
-    throw new SQLException(Constant.METHOD_NOT_SUPPORTED);
+  public void setFetchSize(int fetchSize) throws SQLException {
+    if (fetchSize < 0) {
+      throw new SQLException(
+          String.format(JdbcMessages.FETCH_SIZE_MUST_BE_NON_NEGATIVE, 
fetchSize));
+    }
+    ioTDBRpcDataSet.setFetchSize(fetchSize == 0 ? Config.DEFAULT_FETCH_SIZE : 
fetchSize);
   }
 
   @Override
@@ -720,8 +725,8 @@ public class IoTDBJDBCResultSet implements ResultSet {
 
   @Override
   public Time getTime(int columnIndex) throws SQLException {
-    long time = statement.getMilliSecond(getLong(columnIndex));
-    return new Time(time);
+    long time = getLong(columnIndex);
+    return wasNull() ? null : new Time(statement.getMilliSecond(time));
   }
 
   @Override
@@ -741,12 +746,20 @@ public class IoTDBJDBCResultSet implements ResultSet {
 
   @Override
   public Timestamp getTimestamp(int columnIndex) throws SQLException {
-    return convertToTimestamp(getLong(columnIndex), statement.getTimeFactor());
+    try {
+      return ioTDBRpcDataSet.getTimestamp(columnIndex);
+    } catch (StatementExecutionException e) {
+      throw new SQLException(e.getMessage());
+    }
   }
 
   @Override
   public Timestamp getTimestamp(String columnName) throws SQLException {
-    return new Timestamp(getLong(columnName));
+    try {
+      return ioTDBRpcDataSet.getTimestamp(columnName);
+    } catch (StatementExecutionException e) {
+      throw new SQLException(e.getMessage());
+    }
   }
 
   @Override
diff --git 
a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBJDBCResultSetTest.java
 
b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBJDBCResultSetTest.java
index 208c77295db..b9afc39474f 100644
--- 
a/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBJDBCResultSetTest.java
+++ 
b/iotdb-client/jdbc/src/test/java/org/apache/iotdb/jdbc/IoTDBJDBCResultSetTest.java
@@ -43,6 +43,7 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Timestamp;
 import java.sql.Types;
@@ -153,42 +154,7 @@ public class IoTDBJDBCResultSetTest {
     /*
      * step 1: execute statement
      */
-    List<String> columns = new ArrayList<>();
-    columns.add("root.vehicle.d0.s2");
-    columns.add("root.vehicle.d0.s1");
-    columns.add("root.vehicle.d0.s0");
-    columns.add("root.vehicle.d0.s2");
-
-    List<String> dataTypeList = new ArrayList<>();
-    dataTypeList.add("FLOAT");
-    dataTypeList.add("INT64");
-    dataTypeList.add("INT32");
-    dataTypeList.add("FLOAT");
-
-    when(execResp.isSetColumns()).thenReturn(true);
-    when(execResp.getColumns()).thenReturn(columns);
-    when(execResp.isSetDataTypeList()).thenReturn(true);
-    when(execResp.getDataTypeList()).thenReturn(dataTypeList);
-    when(execResp.isSetOperationType()).thenReturn(true);
-    when(execResp.getOperationType()).thenReturn("QUERY");
-    when(execResp.isSetQueryId()).thenReturn(true);
-    when(execResp.getQueryId()).thenReturn(queryId);
-    when(execResp.isSetTableModel()).thenReturn(false);
-    when(execResp.isIgnoreTimeStamp()).thenReturn(false);
-    List<Integer> columnIndex2TsBlockColumnIndexList = new 
ArrayList<>(columns.size());
-    columnIndex2TsBlockColumnIndexList.add(0);
-    columnIndex2TsBlockColumnIndexList.add(1);
-    columnIndex2TsBlockColumnIndexList.add(2);
-    columnIndex2TsBlockColumnIndexList.add(0);
-
-    when(execResp.getColumnIndex2TsBlockColumnIndexList())
-        .thenReturn(columnIndex2TsBlockColumnIndexList);
-    doReturn("FLOAT")
-        .doReturn("INT64")
-        .doReturn("INT32")
-        .doReturn("FLOAT")
-        .when(fetchMetadataResp)
-        .getDataType();
+    mockVehicleQueryResponse();
 
     boolean hasResultSet = statement.execute(testSql);
     Assert.assertTrue(hasResultSet);
@@ -208,6 +174,18 @@ public class IoTDBJDBCResultSetTest {
       Assert.assertSame(resultSet, resultSet.unwrap(IoTDBJDBCResultSet.class));
       Assert.assertSame(resultSet, resultSet.unwrap(ResultSet.class));
       Assert.assertEquals(ResultSet.HOLD_CURSORS_OVER_COMMIT, 
resultSet.getHoldability());
+      Assert.assertEquals(ResultSet.FETCH_FORWARD, 
resultSet.getFetchDirection());
+      resultSet.setFetchDirection(ResultSet.FETCH_FORWARD);
+      Assert.assertThrows(
+          SQLException.class, () -> 
resultSet.setFetchDirection(ResultSet.FETCH_REVERSE));
+      Assert.assertEquals(Config.DEFAULT_FETCH_SIZE, resultSet.getFetchSize());
+      resultSet.setFetchSize(123);
+      Assert.assertEquals(123, resultSet.getFetchSize());
+      resultSet.setFetchSize(0);
+      Assert.assertEquals(Config.DEFAULT_FETCH_SIZE, resultSet.getFetchSize());
+      Assert.assertThrows(SQLException.class, () -> 
resultSet.setFetchSize(-1));
+      Assert.assertNull(resultSet.getWarnings());
+      resultSet.clearWarnings();
 
       // check columnInfoMap
       Assert.assertEquals(1, resultSet.findColumn("Time"));
@@ -236,7 +214,17 @@ public class IoTDBJDBCResultSetTest {
         resultStr.append(resultSetMetaData.getColumnName(i)).append(",");
       }
       resultStr.append("\n");
+      boolean firstRow = true;
       while (resultSet.next()) { // data
+        if (firstRow) {
+          Assert.assertNull(resultSet.getDate(4));
+          Assert.assertTrue(resultSet.wasNull());
+          Assert.assertNull(resultSet.getTime(4));
+          Assert.assertTrue(resultSet.wasNull());
+          Assert.assertNull(resultSet.getTimestamp(4));
+          Assert.assertTrue(resultSet.wasNull());
+          firstRow = false;
+        }
         for (int i = 1; i <= colCount; i++) {
           resultStr.append(resultSet.getString(i)).append(",");
           resultObjectList.add(resultSet.getObject(i));
@@ -268,6 +256,59 @@ public class IoTDBJDBCResultSetTest {
     verify(fetchResultsResp, times(0)).getStatus();
   }
 
+  @SuppressWarnings("resource")
+  @Test
+  public void testTimestampByNameUsesConnectionTimePrecision() throws 
Exception {
+    when(connection.getTimeFactor()).thenReturn(1_000_000);
+    mockVehicleQueryResponse();
+
+    Assert.assertTrue(statement.execute("select * from root.vehicle.d0"));
+
+    try (ResultSet resultSet = statement.getResultSet()) {
+      Assert.assertTrue(resultSet.next());
+      Assert.assertEquals(resultSet.getTimestamp(1), 
resultSet.getTimestamp("Time"));
+    }
+  }
+
+  private void mockVehicleQueryResponse() {
+    List<String> columns = new ArrayList<>();
+    columns.add("root.vehicle.d0.s2");
+    columns.add("root.vehicle.d0.s1");
+    columns.add("root.vehicle.d0.s0");
+    columns.add("root.vehicle.d0.s2");
+
+    List<String> dataTypeList = new ArrayList<>();
+    dataTypeList.add("FLOAT");
+    dataTypeList.add("INT64");
+    dataTypeList.add("INT32");
+    dataTypeList.add("FLOAT");
+
+    when(execResp.isSetColumns()).thenReturn(true);
+    when(execResp.getColumns()).thenReturn(columns);
+    when(execResp.isSetDataTypeList()).thenReturn(true);
+    when(execResp.getDataTypeList()).thenReturn(dataTypeList);
+    when(execResp.isSetOperationType()).thenReturn(true);
+    when(execResp.getOperationType()).thenReturn("QUERY");
+    when(execResp.isSetQueryId()).thenReturn(true);
+    when(execResp.getQueryId()).thenReturn(queryId);
+    when(execResp.isSetTableModel()).thenReturn(false);
+    when(execResp.isIgnoreTimeStamp()).thenReturn(false);
+    List<Integer> columnIndex2TsBlockColumnIndexList = new 
ArrayList<>(columns.size());
+    columnIndex2TsBlockColumnIndexList.add(0);
+    columnIndex2TsBlockColumnIndexList.add(1);
+    columnIndex2TsBlockColumnIndexList.add(2);
+    columnIndex2TsBlockColumnIndexList.add(0);
+
+    when(execResp.getColumnIndex2TsBlockColumnIndexList())
+        .thenReturn(columnIndex2TsBlockColumnIndexList);
+    doReturn("FLOAT")
+        .doReturn("INT64")
+        .doReturn("INT32")
+        .doReturn("FLOAT")
+        .when(fetchMetadataResp)
+        .getDataType();
+  }
+
   private void constructObjectList(List<Object> standardObject) {
     Object[][] input = {
       {

Reply via email to