This is an automated email from the ASF dual-hosted git repository.

jackietien pushed a commit to branch force_ci/object_type
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 7a62fadd265bd1a87960bebb75d54e3ee6b220a5
Author: JackieTien97 <[email protected]>
AuthorDate: Wed Nov 26 20:26:20 2025 +0800

    Add IT for session and jdbc query
---
 .../iotdb/itbase/runtime/ClusterTestResultSet.java |  16 +-
 .../it/query/object/IoTDBObjectQueryIT.java        | 186 +++++++++++++++++++++
 .../org/apache/iotdb/jdbc/IoTDBJDBCResultSet.java  |   2 +-
 .../relational/ColumnTransformerBuilder.java       |   7 +-
 4 files changed, 202 insertions(+), 9 deletions(-)

diff --git 
a/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/ClusterTestResultSet.java
 
b/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/ClusterTestResultSet.java
index e98ff7e7c14..64c18db11a8 100644
--- 
a/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/ClusterTestResultSet.java
+++ 
b/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/ClusterTestResultSet.java
@@ -781,8 +781,12 @@ public class ClusterTestResultSet implements ResultSet {
   }
 
   @Override
-  public Blob getBlob(int columnIndex) {
-    throw new UnsupportedOperationException();
+  public Blob getBlob(int columnIndex) throws SQLException {
+    RequestDelegate<Blob> delegate = createLocalRequestDelegate();
+    for (ResultSet rs : resultSets) {
+      delegate.addRequest(() -> rs.getBlob(columnIndex));
+    }
+    return delegate.requestAllAndCompare();
   }
 
   @Override
@@ -806,8 +810,12 @@ public class ClusterTestResultSet implements ResultSet {
   }
 
   @Override
-  public Blob getBlob(String columnLabel) {
-    throw new UnsupportedOperationException();
+  public Blob getBlob(String columnLabel) throws SQLException {
+    RequestDelegate<Blob> delegate = createLocalRequestDelegate();
+    for (ResultSet rs : resultSets) {
+      delegate.addRequest(() -> rs.getBlob(columnLabel));
+    }
+    return delegate.requestAllAndCompare();
   }
 
   @Override
diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/object/IoTDBObjectQueryIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/object/IoTDBObjectQueryIT.java
new file mode 100644
index 00000000000..4fad2d2696b
--- /dev/null
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/object/IoTDBObjectQueryIT.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.relational.it.query.object;
+
+import org.apache.iotdb.isession.ITableSession;
+import org.apache.iotdb.isession.SessionConfig;
+import org.apache.iotdb.isession.SessionDataSet;
+import org.apache.iotdb.it.env.EnvFactory;
+import org.apache.iotdb.it.framework.IoTDBTestRunner;
+import org.apache.iotdb.itbase.category.TableClusterIT;
+import org.apache.iotdb.itbase.category.TableLocalStandaloneIT;
+import org.apache.iotdb.itbase.env.BaseEnv;
+import org.apache.iotdb.rpc.IoTDBConnectionException;
+import org.apache.iotdb.rpc.StatementExecutionException;
+
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.read.common.Field;
+import org.apache.tsfile.read.common.RowRecord;
+import org.apache.tsfile.utils.Binary;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import static org.apache.iotdb.db.it.utils.TestUtils.prepareTableData;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+@RunWith(IoTDBTestRunner.class)
+@Category({TableLocalStandaloneIT.class, TableClusterIT.class})
+public class IoTDBObjectQueryIT {
+
+  private static final String DATABASE_NAME = "test_db";
+
+  private static final String TIME_ZONE = "+00:00";
+
+  private static final String[] createSqls =
+      new String[] {
+        "CREATE DATABASE " + DATABASE_NAME,
+        "USE " + DATABASE_NAME,
+        "CREATE TABLE t1(device_id STRING TAG, o1 OBJECT, b1 BLOB, s1 STRING)",
+        "INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(1, 'd1', 
X'cafebabe01', to_object(true, 0, X'cafebabe01'), 'cafebabe01')",
+        "INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(2, 'd1', 
X'cafebabe0202', to_object(true, 0, X'cafebabe02'), 'cafebabe02')",
+        "INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(3, 'd1', 
X'cafebabe0303', to_object(true, 0, X'cafebabe03'), 'cafebabe03')",
+        "INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(4, 'd1', 
X'cafebabe04', to_object(true, 0, X'cafebabe04'), 'cafebabe04')",
+        "INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(1, 'd2', 
X'cafebade01', to_object(true, 0, X'cafebade01'), 'cafebade01')",
+        "INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(2, 'd2', 
X'cafebade0202', to_object(true, 0, X'cafebade02'), 'cafebade02')",
+        "INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(3, 'd2', 
X'cafebade0302', to_object(true, 0, X'cafebade03'), 'cafebade03')",
+        "INSERT INTO t1(time, device_id, b1, o1, s1) VALUES(4, 'd2', 
X'cafebade04', to_object(true, 0, X'cafebade04'), 'cafebade04')",
+        "FLUSH",
+      };
+
+  @BeforeClass
+  public static void classSetUp() {
+    EnvFactory.getEnv().initClusterEnvironment();
+    prepareTableData(createSqls);
+  }
+
+  @AfterClass
+  public static void classTearDown() {
+    EnvFactory.getEnv().cleanClusterEnvironment();
+  }
+
+  @Test
+  public void jdbcTest() {
+    try (Connection connection =
+        EnvFactory.getEnv()
+            .getConnection(
+                SessionConfig.DEFAULT_USER,
+                SessionConfig.DEFAULT_PASSWORD,
+                BaseEnv.TABLE_SQL_DIALECT)) {
+      connection.setClientInfo("time_zone", TIME_ZONE);
+      try (Statement statement = connection.createStatement()) {
+        statement.execute("use " + DATABASE_NAME);
+        try (ResultSet resultSet =
+            statement.executeQuery(
+                "SELECT time, b1, o1, s1 FROM t1 WHERE device_id = 'd1' ORDER 
BY time")) {
+          int cnt = 0;
+          while (resultSet.next()) {
+            cnt++;
+            Blob blob = resultSet.getBlob(3);
+            byte[] bytes = resultSet.getBytes("o1");
+            assertArrayEquals(blob.getBytes(1, (int) blob.length()), bytes);
+            assertTrue(new String(bytes).endsWith(String.format("%d.bin", 
cnt)));
+            String s = resultSet.getString(3);
+            assertEquals("(Object) 5 B", s);
+          }
+          assertEquals(4, cnt);
+        }
+
+        try (ResultSet resultSet =
+            statement.executeQuery(
+                "SELECT time, b1, READ_OBJECT(o1), s1 FROM t1 WHERE device_id 
= 'd2' AND READ_OBJECT(o1)=b1 ORDER BY time")) {
+          int cnt = 0;
+          String[] ans = {"0xcafebade01", "0xcafebade04"};
+          while (resultSet.next()) {
+            String s = resultSet.getString(3);
+            assertEquals(ans[cnt], s);
+            cnt++;
+          }
+          assertEquals(2, cnt);
+        }
+      }
+    } catch (SQLException e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+  }
+
+  @Test
+  public void sessionTest() {
+    try (ITableSession session = 
EnvFactory.getEnv().getTableSessionConnection()) {
+      session.executeNonQueryStatement("USE " + DATABASE_NAME);
+
+      // SessionDataSet
+      try (SessionDataSet dataSet =
+          session.executeQueryStatement(
+              "SELECT time, b1, o1, s1 FROM t1 WHERE device_id = 'd1' ORDER BY 
time")) {
+        int cnt = 0;
+        while (dataSet.hasNext()) {
+          cnt++;
+          RowRecord rowRecord = dataSet.next();
+          Field field = rowRecord.getField(2);
+          String s = field.getStringValue();
+          assertEquals("(Object) 5 B", s);
+          Object blob = field.getObjectValue(TSDataType.OBJECT);
+          assertTrue(blob instanceof Binary);
+          assertTrue(
+              new String(((Binary) 
blob).getValues()).endsWith(String.format("%d.bin", cnt)));
+
+          Binary binary = field.getBinaryV();
+          assertArrayEquals(binary.getValues(), ((Binary) blob).getValues());
+          assertTrue(new 
String(binary.getValues()).endsWith(String.format("%d.bin", cnt)));
+        }
+        assertEquals(4, cnt);
+      }
+
+      // SessionDataSet.DataIterator
+      try (SessionDataSet dataSet =
+          session.executeQueryStatement(
+              "SELECT time, b1, o1, s1 FROM t1 WHERE device_id = 'd2' ORDER BY 
time")) {
+        SessionDataSet.DataIterator iterator = dataSet.iterator();
+        int cnt = 0;
+        while (iterator.next()) {
+          cnt++;
+          Object o = iterator.getObject(3);
+          assertTrue(o instanceof String);
+          assertEquals("(Object) 5 B", o);
+          String s = iterator.getString("o1");
+          assertEquals("(Object) 5 B", s);
+          Binary blob = iterator.getBlob(3);
+          assertTrue(new 
String(blob.getValues()).endsWith(String.format("%d.bin", cnt)));
+        }
+        assertEquals(4, cnt);
+      }
+    } catch (IoTDBConnectionException | StatementExecutionException e) {
+      fail(e.getMessage());
+    }
+  }
+}
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 77ae98d4887..ff00e3b35df 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
@@ -380,7 +380,7 @@ public class IoTDBJDBCResultSet implements ResultSet {
         return null;
       }
 
-      if (dataType.equals(TSDataType.BLOB)) {
+      if (dataType.equals(TSDataType.BLOB) || 
dataType.equals(TSDataType.OBJECT)) {
         Binary binary = ioTDBRpcDataSet.getBinary(columnName);
         return binary == null ? null : binary.getValues();
       } else {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
index 0378c80f042..8f2c82d6f1c 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/relational/ColumnTransformerBuilder.java
@@ -243,7 +243,6 @@ import static 
org.apache.tsfile.read.common.type.DoubleType.DOUBLE;
 import static org.apache.tsfile.read.common.type.FloatType.FLOAT;
 import static org.apache.tsfile.read.common.type.IntType.INT32;
 import static org.apache.tsfile.read.common.type.LongType.INT64;
-import static org.apache.tsfile.read.common.type.ObjectType.OBJECT;
 import static org.apache.tsfile.read.common.type.StringType.STRING;
 
 public class ColumnTransformerBuilder
@@ -1456,10 +1455,10 @@ public class ColumnTransformerBuilder
         .equalsIgnoreCase(functionName)) {
       ColumnTransformer first = this.process(children.get(0), context);
       if (children.size() == 1) {
-        return new ReadObjectColumnTransformer(OBJECT, first, 
context.fragmentInstanceContext);
+        return new ReadObjectColumnTransformer(BLOB, first, 
context.fragmentInstanceContext);
       } else if (children.size() == 2) {
         return new ReadObjectColumnTransformer(
-            OBJECT,
+            BLOB,
             ((LongLiteral) children.get(1)).getParsedValue(),
             first,
             context.fragmentInstanceContext);
@@ -1468,7 +1467,7 @@ public class ColumnTransformerBuilder
         long length = ((LongLiteral) children.get(2)).getParsedValue();
         checkArgument(offset >= 0 && length >= 0);
         return new ReadObjectColumnTransformer(
-            OBJECT,
+            BLOB,
             ((LongLiteral) children.get(1)).getParsedValue(),
             ((LongLiteral) children.get(2)).getParsedValue(),
             first,

Reply via email to