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 = {
{