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

critas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new fbc28c6e27a Fixed issues in the rest service module: BLOB, DATE, table 
model parameters, and added statistical delay monitoring items to 
FastLastQuery. (#15917)
fbc28c6e27a is described below

commit fbc28c6e27a12cb01a69d64d796138545fe2b457
Author: CloudWise-Lukemiao <[email protected]>
AuthorDate: Tue Jul 22 15:46:28 2025 +0800

    Fixed issues in the rest service module: BLOB, DATE, table model 
parameters, and added statistical delay monitoring items to FastLastQuery. 
(#15917)
    
    * The following issues have been fixed:
    1、When querying BLOB data type through the /rest/v2/query interface, the 
returned results display garbled characters.
    2、For the DATE data type, it is recommended that the returned results be 
displayed with separators, such as: 2025-01-01.
    3、Added statistical delay monitoring items to FastLastQuery.
    4、Fixed the spelling error of the column_categories parameter in the 
insertTablet method of the table model.
    
    * add it
    
    * add it
    
    * add it
    
    * add it
---
 .../java/org/apache/iotdb/TableHttpExample.java    |   2 +-
 .../java/org/apache/iotdb/TableHttpsExample.java   |   2 +-
 .../org/apache/iotdb/db/it/IoTDBRestServiceIT.java | 145 ++++++++++++++++++++-
 .../relational/it/rest/it/IoTDBRestServiceIT.java  |  32 ++++-
 .../rest/table/v1/handler/QueryDataSetHandler.java |  36 +++--
 .../table/v1/handler/RequestValidationHandler.java |  12 +-
 .../v1/handler/StatementConstructionHandler.java   |   4 +-
 .../rest/v1/handler/QueryDataSetHandler.java       |  54 ++++++--
 .../rest/v2/handler/QueryDataSetHandler.java       |  37 ++++--
 .../protocol/rest/v2/impl/RestApiServiceImpl.java  |  13 +-
 .../queryengine/plan/statement/StatementType.java  |   4 +-
 .../src/main/openapi3/iotdb_rest_table_v1.yaml     |   2 +-
 12 files changed, 292 insertions(+), 51 deletions(-)

diff --git 
a/example/rest-java-example/src/main/java/org/apache/iotdb/TableHttpExample.java
 
b/example/rest-java-example/src/main/java/org/apache/iotdb/TableHttpExample.java
index ba419eddd7f..b9651245d02 100644
--- 
a/example/rest-java-example/src/main/java/org/apache/iotdb/TableHttpExample.java
+++ 
b/example/rest-java-example/src/main/java/org/apache/iotdb/TableHttpExample.java
@@ -93,7 +93,7 @@ public class TableHttpExample {
     try {
       HttpPost httpPost = 
getHttpPost("http://127.0.0.1:18080/rest/table/v1/insertTablet";);
       String json =
-          
"{\"database\":\"test\",\"column_catogories\":[\"TAG\",\"ATTRIBUTE\",\"FIELD\"],\"timestamps\":[1635232143960,1635232153960,1635232163960,1635232173960,1635232183960],\"column_names\":[\"id1\",\"t1\",\"s1\"],\"data_types\":[\"STRING\",\"STRING\",\"FLOAT\"],\"values\":[[\"a11\",\"true\",11333],[\"a11\",\"false\",22333],[\"a13\",\"false1\",23333],[\"a14\",\"false2\",24],[\"a15\",\"false3\",25]],\"table\":\"sg211\"}";
+          
"{\"database\":\"test\",\"column_categories\":[\"TAG\",\"ATTRIBUTE\",\"FIELD\"],\"timestamps\":[1635232143960,1635232153960,1635232163960,1635232173960,1635232183960],\"column_names\":[\"id1\",\"t1\",\"s1\"],\"data_types\":[\"STRING\",\"STRING\",\"FLOAT\"],\"values\":[[\"a11\",\"true\",11333],[\"a11\",\"false\",22333],[\"a13\",\"false1\",23333],[\"a14\",\"false2\",24],[\"a15\",\"false3\",25]],\"table\":\"sg211\"}";
       httpPost.setEntity(new StringEntity(json, Charset.defaultCharset()));
       response = httpClient.execute(httpPost);
       HttpEntity responseEntity = response.getEntity();
diff --git 
a/example/rest-java-example/src/main/java/org/apache/iotdb/TableHttpsExample.java
 
b/example/rest-java-example/src/main/java/org/apache/iotdb/TableHttpsExample.java
index c6d8d4709e4..200dbf66fdb 100644
--- 
a/example/rest-java-example/src/main/java/org/apache/iotdb/TableHttpsExample.java
+++ 
b/example/rest-java-example/src/main/java/org/apache/iotdb/TableHttpsExample.java
@@ -93,7 +93,7 @@ public class TableHttpsExample {
     try {
       HttpPost httpPost = 
getHttpPost("https://127.0.0.1:18080/rest/table/v1/insertTablet";);
       String json =
-          
"{\"database\":\"test\",\"column_catogories\":[\"TAG\",\"ATTRIBUTE\",\"FIELD\"],\"timestamps\":[1635232143960,1635232153960,1635232163960,1635232173960,1635232183960],\"column_names\":[\"id1\",\"t1\",\"s1\"],\"data_types\":[\"STRING\",\"STRING\",\"FLOAT\"],\"values\":[[\"a11\",\"true\",11333],[\"a11\",\"false\",22333],[\"a13\",\"false1\",23333],[\"a14\",\"false2\",24],[\"a15\",\"false3\",25]],\"table\":\"sg211\"}";
+          
"{\"database\":\"test\",\"column_categories\":[\"TAG\",\"ATTRIBUTE\",\"FIELD\"],\"timestamps\":[1635232143960,1635232153960,1635232163960,1635232173960,1635232183960],\"column_names\":[\"id1\",\"t1\",\"s1\"],\"data_types\":[\"STRING\",\"STRING\",\"FLOAT\"],\"values\":[[\"a11\",\"true\",11333],[\"a11\",\"false\",22333],[\"a13\",\"false1\",23333],[\"a14\",\"false2\",24],[\"a15\",\"false3\",25]],\"table\":\"sg211\"}";
       httpPost.setEntity(new StringEntity(json, Charset.defaultCharset()));
       response = httpClient.execute(httpPost);
       HttpEntity responseEntity = response.getEntity();
diff --git 
a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBRestServiceIT.java 
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBRestServiceIT.java
index 7cde457761c..42dd2587881 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBRestServiceIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBRestServiceIT.java
@@ -385,7 +385,6 @@ public class IoTDBRestServiceIT {
   @Test
   public void insertAndQuery() {
     CloseableHttpClient httpClient = HttpClientBuilder.create().build();
-    //
     rightInsertTablet(httpClient);
     query(httpClient);
     queryGroupByLevel(httpClient);
@@ -717,7 +716,7 @@ public class IoTDBRestServiceIT {
         errorInsertRecords(httpClient, json, hp);
       }
     }
-
+    insertDate();
     try {
       httpClient.close();
     } catch (IOException e) {
@@ -2122,4 +2121,146 @@ public class IoTDBRestServiceIT {
     Assert.assertEquals(values2.get(0), valuesResult.get(1).get(0));
     Assert.assertEquals(values3, valuesResult.get(2));
   }
+
+  public void insertDate() {
+    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+    HttpPost httpPost2 = getHttpPost("http://127.0.0.1:"; + port + 
"/rest/v1/nonQuery");
+    HttpPost httpPostV2 = getHttpPost("http://127.0.0.1:"; + port + 
"/rest/v2/nonQuery");
+    nonQuery(
+        httpClient,
+        "{\"sql\":\"CREATE TIMESERIES root.sg1.d1.s4 WITH DATATYPE=DATE, 
ENCODING=PLAIN, COMPRESSOR=SNAPPY\"}",
+        httpPost2);
+    nonQuery(
+        httpClient,
+        "{\"sql\":\"CREATE TIMESERIES root.sg1.d1.s5 WITH DATATYPE=Blob, 
ENCODING=PLAIN, COMPRESSOR=SNAPPY\"}",
+        httpPost2);
+
+    String sql =
+        "{\"sql\":\"insert into root.sg1.d1(time,s4,s5) 
values(1,'2025-07-14',\\\"X'cafebabe'\\\")\"}";
+    nonQuery(httpClient, sql, httpPost2);
+    queryDateAndBlob(httpClient);
+    queryDateAndBlobV2(httpClient);
+  }
+
+  public void queryDateAndBlob(CloseableHttpClient httpClient) {
+    CloseableHttpResponse response = null;
+    try {
+      HttpPost httpPost = getHttpPost("http://127.0.0.1:"; + port + 
"/rest/v1/query");
+      String sql = "{\"sql\":\"select s4,s5 from root.sg1.d1\"}";
+      httpPost.setEntity(new StringEntity(sql, Charset.defaultCharset()));
+      response = httpClient.execute(httpPost);
+      HttpEntity responseEntity = response.getEntity();
+      String message = EntityUtils.toString(responseEntity, "utf-8");
+      ObjectMapper mapper = new ObjectMapper();
+      Map map = mapper.readValue(message, Map.class);
+      List<Long> timestampsResult = (List<Long>) map.get("timestamps");
+      List<Long> expressionsResult = (List<Long>) map.get("expressions");
+      List<List<Object>> valuesResult = (List<List<Object>>) map.get("values");
+      Assert.assertTrue(map.size() > 0);
+      List<Object> expressions =
+          new ArrayList<Object>() {
+            {
+              add("root.sg1.d1.s4");
+              add("root.sg1.d1.s5");
+            }
+          };
+      List<Object> timestamps =
+          new ArrayList<Object>() {
+            {
+              add(1);
+            }
+          };
+      List<Object> values1 =
+          new ArrayList<Object>() {
+            {
+              add("2025-07-14");
+            }
+          };
+      List<Object> values2 =
+          new ArrayList<Object>() {
+            {
+              add("0xcafebabe");
+            }
+          };
+
+      Assert.assertEquals(expressions, expressionsResult);
+      Assert.assertEquals(timestamps, timestampsResult);
+      Assert.assertEquals(values1, valuesResult.get(0));
+      Assert.assertEquals(values2, valuesResult.get(1));
+
+    } catch (IOException e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    } finally {
+      try {
+        if (response != null) {
+          response.close();
+        }
+      } catch (IOException e) {
+        e.printStackTrace();
+        fail(e.getMessage());
+      }
+    }
+  }
+
+  public void queryDateAndBlobV2(CloseableHttpClient httpClient) {
+    CloseableHttpResponse response = null;
+    try {
+      HttpPost httpPost = getHttpPost("http://127.0.0.1:"; + port + 
"/rest/v2/query");
+      String sql = "{\"sql\":\"select s4,s5 from root.sg1.d1\"}";
+      httpPost.setEntity(new StringEntity(sql, Charset.defaultCharset()));
+      response = httpClient.execute(httpPost);
+      HttpEntity responseEntity = response.getEntity();
+      String message = EntityUtils.toString(responseEntity, "utf-8");
+      ObjectMapper mapper = new ObjectMapper();
+      Map map = mapper.readValue(message, Map.class);
+      List<Long> timestampsResult = (List<Long>) map.get("timestamps");
+      List<Long> expressionsResult = (List<Long>) map.get("expressions");
+      List<List<Object>> valuesResult = (List<List<Object>>) map.get("values");
+      Assert.assertTrue(map.size() > 0);
+      List<Object> expressions =
+          new ArrayList<Object>() {
+            {
+              add("root.sg1.d1.s4");
+              add("root.sg1.d1.s5");
+            }
+          };
+      List<Object> timestamps =
+          new ArrayList<Object>() {
+            {
+              add(1);
+            }
+          };
+      List<Object> values1 =
+          new ArrayList<Object>() {
+            {
+              add("2025-07-14");
+            }
+          };
+      List<Object> values2 =
+          new ArrayList<Object>() {
+            {
+              add("0xcafebabe");
+            }
+          };
+
+      Assert.assertEquals(expressions, expressionsResult);
+      Assert.assertEquals(timestamps, timestampsResult);
+      Assert.assertEquals(values1, valuesResult.get(0));
+      Assert.assertEquals(values2, valuesResult.get(1));
+
+    } catch (IOException e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    } finally {
+      try {
+        if (response != null) {
+          response.close();
+        }
+      } catch (IOException e) {
+        e.printStackTrace();
+        fail(e.getMessage());
+      }
+    }
+  }
 }
diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/rest/it/IoTDBRestServiceIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/rest/it/IoTDBRestServiceIT.java
index 156ecdeed32..0ee6d7afe5d 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/rest/it/IoTDBRestServiceIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/rest/it/IoTDBRestServiceIT.java
@@ -147,6 +147,7 @@ public class IoTDBRestServiceIT {
     testQuery();
     testQuery1();
     testQuery2();
+    inertDateAndBlob();
   }
 
   public void testQuery() {
@@ -277,7 +278,7 @@ public class IoTDBRestServiceIT {
       RestUtils.nonQuery(httpClient, port, sqlHandler("test", sql));
     }
     String json =
-        
"{\"database\":\"test\",\"column_catogories\":[\"TAG\",\"ATTRIBUTE\",\"FIELD\"],\"timestamps\":[1635232143960,1635232153960,1635232163960,1635232173960,1635232183960],\"column_names\":[\"tag1\",\"t1\",\"s1\"],\"data_types\":[\"STRING\",\"STRING\",\"FLOAT\"],\"values\":[[\"a11\",\"true\",11],[\"a11\",\"false\",22],[\"a13\",\"false1\",23],[\"a14\",\"false2\",24],[\"a15\",\"false3\",25]],\"table\":\"sg211\"}";
+        
"{\"database\":\"test\",\"column_categories\":[\"TAG\",\"ATTRIBUTE\",\"FIELD\"],\"timestamps\":[1635232143960,1635232153960,1635232163960,1635232173960,1635232183960],\"column_names\":[\"tag1\",\"t1\",\"s1\"],\"data_types\":[\"STRING\",\"STRING\",\"FLOAT\"],\"values\":[[\"a11\",\"true\",11],[\"a11\",\"false\",22],[\"a13\",\"false1\",23],[\"a14\",\"false2\",24],[\"a15\",\"false3\",25]],\"table\":\"sg211\"}";
     rightInsertTablet(json);
   }
 
@@ -289,7 +290,7 @@ public class IoTDBRestServiceIT {
       RestUtils.nonQuery(httpClient, port, sqlHandler("test", sql));
     }
     String json =
-        
"{\"database\":\"\",\"column_catogories\":[\"TAG\",\"ATTRIBUTE\",\"FIELD\"],\"timestamps\":[1635232143960,1635232153960,1635232163960,1635232173960,1635232183960],\"column_names\":[\"tag1\",\"t1\",\"s1\"],\"data_types\":[\"STRING\",\"STRING\",\"FLOAT\"],\"values\":[[\"a11\",\"true\",11],[\"a11\",\"false\",22],[\"a13\",\"false1\",23],[\"a14\",\"false2\",24],[\"a15\",\"false3\",25]],\"table\":\"sg211\"}";
+        
"{\"database\":\"\",\"column_categories\":[\"TAG\",\"ATTRIBUTE\",\"FIELD\"],\"timestamps\":[1635232143960,1635232153960,1635232163960,1635232173960,1635232183960],\"column_names\":[\"tag1\",\"t1\",\"s1\"],\"data_types\":[\"STRING\",\"STRING\",\"FLOAT\"],\"values\":[[\"a11\",\"true\",11],[\"a11\",\"false\",22],[\"a13\",\"false1\",23],[\"a14\",\"false2\",24],[\"a15\",\"false3\",25]],\"table\":\"sg211\"}";
     JsonObject result = RestUtils.insertTablet(httpClient, port, json);
     assertEquals(305, Integer.parseInt(result.get("code").toString()));
   }
@@ -302,11 +303,11 @@ public class IoTDBRestServiceIT {
       RestUtils.nonQuery(httpClient, port, sqlHandler("test", sql));
     }
     String json =
-        
"{\"database\":\"test\",\"column_catogories\":[\"ATTRIBUTE\",\"FIELD\"],\"timestamps\":[1635232143960,1635232153960,1635232163960,1635232173960,1635232183960],\"column_names\":[\"id1\",\"t1\",\"s1\"],\"data_types\":[\"STRING\",\"STRING\",\"FLOAT\"],\"values\":[[\"a11\",\"true\",11],[\"a11\",\"false\",22],[\"a13\",\"false1\",23],[\"a14\",\"false2\",24],[\"a15\",\"false3\",25]],\"table\":\"sg211\"}";
+        
"{\"database\":\"test\",\"column_categories\":[\"ATTRIBUTE\",\"FIELD\"],\"timestamps\":[1635232143960,1635232153960,1635232163960,1635232173960,1635232183960],\"column_names\":[\"id1\",\"t1\",\"s1\"],\"data_types\":[\"STRING\",\"STRING\",\"FLOAT\"],\"values\":[[\"a11\",\"true\",11],[\"a11\",\"false\",22],[\"a13\",\"false1\",23],[\"a14\",\"false2\",24],[\"a15\",\"false3\",25]],\"table\":\"sg211\"}";
     JsonObject result = RestUtils.insertTablet(httpClient, port, json);
     assertEquals(305, Integer.parseInt(result.get("code").toString()));
     assertEquals(
-        "column_names and column_catogories should have the same 
size,column_catogories and data_types should have the same size",
+        "column_names and column_categories should have the same 
size,column_categories and data_types should have the same size",
         result.get("message").getAsString());
   }
 
@@ -318,7 +319,7 @@ public class IoTDBRestServiceIT {
       RestUtils.nonQuery(httpClient, port, sqlHandler("test", sql));
     }
     String json =
-        
"{\"database\":\"test\",\"column_catogories\":[\"TAG\",\"ATTRIBUTE\",\"FIELD\"],\"timestamps\":[1635232143960,1635232153960,1635232163960,1635232183960],\"column_names\":[\"tag1\",\"t1\",\"s1\"],\"data_types\":[\"STRING\",\"STRING\",\"FLOAT\"],\"values\":[[\"a11\",\"true\",11],[\"a11\",\"false\",22],[\"a13\",\"false1\",23],[\"a14\",\"false2\",24],[\"a15\",\"false3\",25]],\"table\":\"sg211\"}";
+        
"{\"database\":\"test\",\"column_categories\":[\"TAG\",\"ATTRIBUTE\",\"FIELD\"],\"timestamps\":[1635232143960,1635232153960,1635232163960,1635232183960],\"column_names\":[\"tag1\",\"t1\",\"s1\"],\"data_types\":[\"STRING\",\"STRING\",\"FLOAT\"],\"values\":[[\"a11\",\"true\",11],[\"a11\",\"false\",22],[\"a13\",\"false1\",23],[\"a14\",\"false2\",24],[\"a15\",\"false3\",25]],\"table\":\"sg211\"}";
     JsonObject result = RestUtils.insertTablet(httpClient, port, json);
     assertEquals(305, Integer.parseInt(result.get("code").toString()));
     assertEquals(
@@ -350,4 +351,25 @@ public class IoTDBRestServiceIT {
       RestUtils.nonQuery(httpClient, port, jsonObject.toString());
     }
   }
+
+  public void inertDateAndBlob() {
+    RestUtils.nonQuery(httpClient, port, sqlHandler("", "create database 
test"));
+    String sql = "CREATE TABLE tt (time TIMESTAMP TIME,d Blob FIELD,e date 
FIELD)";
+    JsonObject result = RestUtils.nonQuery(httpClient, port, 
sqlHandler("test", sql));
+
+    assertEquals(200, Integer.parseInt(result.get("code").toString()));
+    String insertSql = "insert into tt(time,e,d) 
values(1,'2025-07-14',X'cafebabe')";
+    result = RestUtils.nonQuery(httpClient, port, sqlHandler("test", 
insertSql));
+    System.out.println(result);
+    assertEquals(200, Integer.parseInt(result.get("code").toString()));
+
+    JsonObject queryResult =
+        RestUtils.query(httpClient, port, sqlHandler("test", "select time,e,d 
from tt"));
+    JsonArray jsonArray = queryResult.get("values").getAsJsonArray();
+    System.out.println(jsonArray);
+    JsonArray jsonArray1 = jsonArray.get(0).getAsJsonArray();
+    assertEquals(1, jsonArray1.get(0).getAsInt());
+    assertEquals("2025-07-14", jsonArray1.get(1).getAsString());
+    assertEquals("0xcafebabe", jsonArray1.get(2).getAsString());
+  }
 }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/table/v1/handler/QueryDataSetHandler.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/table/v1/handler/QueryDataSetHandler.java
index 149b99fc028..25e331b38a8 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/table/v1/handler/QueryDataSetHandler.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/table/v1/handler/QueryDataSetHandler.java
@@ -30,6 +30,8 @@ import org.apache.tsfile.block.column.Column;
 import org.apache.tsfile.common.conf.TSFileConfig;
 import org.apache.tsfile.enums.TSDataType;
 import org.apache.tsfile.read.common.block.TsBlock;
+import org.apache.tsfile.utils.BytesUtils;
+import org.apache.tsfile.utils.DateUtils;
 
 import javax.ws.rs.core.Response;
 
@@ -101,10 +103,7 @@ public class QueryDataSetHandler {
           if (column.isNull(i)) {
             targetDataSetColumn.add(null);
           } else {
-            targetDataSetColumn.add(
-                column.getDataType().equals(TSDataType.TEXT)
-                    ? 
column.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET)
-                    : column.getObject(i));
+            addTypedValueToTarget(targetDataSet.getDataTypes(), k, i, 
targetDataSetColumn, column);
           }
         }
         if (k != columnNum - 1) {
@@ -116,6 +115,30 @@ public class QueryDataSetHandler {
     return Response.ok().entity(targetDataSet).build();
   }
 
+  private static void addTypedValueToTarget(
+      List<String> dataTypes,
+      int colIndex,
+      int rowIndex,
+      List<Object> targetColumnList,
+      Column column) {
+    String dataTypeName = dataTypes != null ? dataTypes.get(colIndex) : null;
+
+    if (TSDataType.TEXT.name().equals(dataTypeName)) {
+      
targetColumnList.add(column.getBinary(rowIndex).getStringValue(TSFileConfig.STRING_CHARSET));
+    } else if (TSDataType.DATE.name().equals(dataTypeName)) {
+      int intValue = column.getInt(rowIndex);
+      targetColumnList.add(DateUtils.formatDate(intValue));
+    } else if (TSDataType.BLOB.name().equals(dataTypeName)) {
+      byte[] v = column.getBinary(rowIndex).getValues();
+      targetColumnList.add(BytesUtils.parseBlobByteArrayToString(v));
+    } else {
+      targetColumnList.add(
+          column.getDataType().equals(TSDataType.TEXT)
+              ? 
column.getBinary(rowIndex).getStringValue(TSFileConfig.STRING_CHARSET)
+              : column.getObject(rowIndex));
+    }
+  }
+
   private static Response fillOtherDataSet(
       IQueryExecution queryExecution, final int actualRowSizeLimit) throws 
IoTDBException {
     QueryDataSet targetDataSet = new QueryDataSet();
@@ -184,10 +207,7 @@ public class QueryDataSetHandler {
           if (column.isNull(i)) {
             targetDataSetColumn.add(null);
           } else {
-            targetDataSetColumn.add(
-                column.getDataType().equals(TSDataType.TEXT)
-                    ? 
column.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET)
-                    : column.getObject(i));
+            addTypedValueToTarget(targetDataSet.getDataTypes(), k, i, 
targetDataSetColumn, column);
           }
         }
         if (k != columnNum - 1) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/table/v1/handler/RequestValidationHandler.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/table/v1/handler/RequestValidationHandler.java
index f58e6b447b6..8642f17b562 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/table/v1/handler/RequestValidationHandler.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/table/v1/handler/RequestValidationHandler.java
@@ -43,20 +43,20 @@ public class RequestValidationHandler {
     Objects.requireNonNull(insertTabletRequest.getTable(), "table should not 
be null");
     Objects.requireNonNull(insertTabletRequest.getColumnNames(), "column_names 
should not be null");
     Objects.requireNonNull(
-        insertTabletRequest.getColumnCatogories(), "column_catogories should 
not be null");
+        insertTabletRequest.getColumnCategories(), "column_categories should 
not be null");
     Objects.requireNonNull(insertTabletRequest.getDataTypes(), "data_types 
should not be null");
     Objects.requireNonNull(insertTabletRequest.getTimestamps(), "timestamps 
should not be null");
     Objects.requireNonNull(insertTabletRequest.getValues(), "values should not 
be null");
     List<String> errorMessages = new ArrayList<>();
     String table = insertTabletRequest.getTable();
-    if (insertTabletRequest.getColumnCatogories().size() == 0
-        || insertTabletRequest.getColumnCatogories().size()
+    if (insertTabletRequest.getColumnCategories().size() == 0
+        || insertTabletRequest.getColumnCategories().size()
             != insertTabletRequest.getColumnNames().size()) {
-      errorMessages.add("column_names and column_catogories should have the 
same size");
+      errorMessages.add("column_names and column_categories should have the 
same size");
     }
-    if (insertTabletRequest.getColumnCatogories().size()
+    if (insertTabletRequest.getColumnCategories().size()
         != insertTabletRequest.getDataTypes().size()) {
-      errorMessages.add("column_catogories and data_types should have the same 
size");
+      errorMessages.add("column_categories and data_types should have the same 
size");
     }
     if (insertTabletRequest.getTimestamps().size() != 
insertTabletRequest.getValues().size()) {
       errorMessages.add("values and timestamps should have the same size");
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/table/v1/handler/StatementConstructionHandler.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/table/v1/handler/StatementConstructionHandler.java
index a5a19ebf0d1..70f3cfb826e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/table/v1/handler/StatementConstructionHandler.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/table/v1/handler/StatementConstructionHandler.java
@@ -175,11 +175,11 @@ public class StatementConstructionHandler {
     insertStatement.setAligned(false);
     insertStatement.setWriteToTable(true);
     TsTableColumnCategory[] columnCategories =
-        new 
TsTableColumnCategory[insertTabletReq.getColumnCatogories().size()];
+        new 
TsTableColumnCategory[insertTabletReq.getColumnCategories().size()];
     for (int i = 0; i < columnCategories.length; i++) {
       columnCategories[i] =
           TsTableColumnCategory.fromTsFileColumnCategory(
-              
ColumnCategory.valueOf(insertTabletReq.getColumnCatogories().get(i)));
+              
ColumnCategory.valueOf(insertTabletReq.getColumnCategories().get(i)));
     }
     insertStatement.setColumnCategories(columnCategories);
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v1/handler/QueryDataSetHandler.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v1/handler/QueryDataSetHandler.java
index c82b07c0603..8accae7991b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v1/handler/QueryDataSetHandler.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v1/handler/QueryDataSetHandler.java
@@ -34,6 +34,8 @@ import org.apache.tsfile.block.column.Column;
 import org.apache.tsfile.common.conf.TSFileConfig;
 import org.apache.tsfile.enums.TSDataType;
 import org.apache.tsfile.read.common.block.TsBlock;
+import org.apache.tsfile.utils.BytesUtils;
+import org.apache.tsfile.utils.DateUtils;
 
 import javax.ws.rs.core.Response;
 
@@ -91,8 +93,10 @@ public class QueryDataSetHandler {
         new org.apache.iotdb.db.protocol.rest.v1.model.QueryDataSet();
 
     DatasetHeader datasetHeader = queryExecution.getDatasetHeader();
+    List<TSDataType> dataTypes = new ArrayList<>();
     int[] targetDataSetIndexToSourceDataSetIndex = new 
int[datasetHeader.getRespColumns().size()];
     for (int i = 0; i < datasetHeader.getRespColumns().size(); i++) {
+      dataTypes.add(datasetHeader.getColumnHeaders().get(i).getColumnType());
       targetDataSet.addExpressionsItem(datasetHeader.getRespColumns().get(i));
       targetDataSet.addValuesItem(new ArrayList<>());
       targetDataSetIndexToSourceDataSetIndex[i] =
@@ -100,7 +104,11 @@ public class QueryDataSetHandler {
     }
 
     return fillQueryDataSetWithoutTimestamps(
-        queryExecution, targetDataSetIndexToSourceDataSetIndex, 
actualRowSizeLimit, targetDataSet);
+        queryExecution,
+        targetDataSetIndexToSourceDataSetIndex,
+        actualRowSizeLimit,
+        targetDataSet,
+        dataTypes);
   }
 
   private static Response fillShowPlanDataSet(
@@ -113,7 +121,11 @@ public class QueryDataSetHandler {
         queryExecution.getDatasetHeader(), 
targetDataSetIndexToSourceDataSetIndex, targetDataSet);
 
     return fillQueryDataSetWithoutTimestamps(
-        queryExecution, targetDataSetIndexToSourceDataSetIndex, 
actualRowSizeLimit, targetDataSet);
+        queryExecution,
+        targetDataSetIndexToSourceDataSetIndex,
+        actualRowSizeLimit,
+        targetDataSet,
+        null);
   }
 
   private static void initTargetDatasetOrderByOrderWithSourceDataSet(
@@ -141,6 +153,7 @@ public class QueryDataSetHandler {
     DatasetHeader header = queryExecution.getDatasetHeader();
     List<String> resultColumns = header.getRespColumns();
     Map<String, Integer> headerMap = header.getColumnNameIndexMap();
+    List<TSDataType> dataTypes = header.getRespDataTypes();
     for (String resultColumn : resultColumns) {
       targetDataSet.addExpressionsItem(resultColumn);
       targetDataSet.addValuesItem(new ArrayList<>());
@@ -184,10 +197,7 @@ public class QueryDataSetHandler {
           if (column.isNull(i)) {
             targetDataSetColumn.add(null);
           } else {
-            targetDataSetColumn.add(
-                column.getDataType().equals(TSDataType.TEXT)
-                    ? 
column.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET)
-                    : column.getObject(i));
+            addTypedValueToTarget(dataTypes, k, i, targetDataSetColumn, 
column);
           }
         }
         if (k != columnNum - 1) {
@@ -202,7 +212,8 @@ public class QueryDataSetHandler {
       IQueryExecution queryExecution,
       int[] targetDataSetIndexToSourceDataSetIndex,
       int actualRowSizeLimit,
-      org.apache.iotdb.db.protocol.rest.v1.model.QueryDataSet targetDataSet)
+      org.apache.iotdb.db.protocol.rest.v1.model.QueryDataSet targetDataSet,
+      List<TSDataType> dataTypes)
       throws IoTDBException {
     int fetched = 0;
     int columnNum = queryExecution.getOutputValueColumnCount();
@@ -240,10 +251,7 @@ public class QueryDataSetHandler {
           if (column.isNull(i)) {
             targetDataSetColumn.add(null);
           } else {
-            targetDataSetColumn.add(
-                column.getDataType().equals(TSDataType.TEXT)
-                    ? 
column.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET)
-                    : column.getObject(i));
+            addTypedValueToTarget(dataTypes, k, i, targetDataSetColumn, 
column);
           }
         }
         if (k != columnNum - 1) {
@@ -254,6 +262,30 @@ public class QueryDataSetHandler {
     return Response.ok().entity(targetDataSet).build();
   }
 
+  private static void addTypedValueToTarget(
+      List<TSDataType> dataTypes,
+      int colIndex,
+      int rowIndex,
+      List<Object> targetColumnList,
+      Column column) {
+    String dataTypeName = dataTypes != null ? dataTypes.get(colIndex).name() : 
null;
+
+    if (TSDataType.TEXT.name().equals(dataTypeName)) {
+      
targetColumnList.add(column.getBinary(rowIndex).getStringValue(TSFileConfig.STRING_CHARSET));
+    } else if (TSDataType.DATE.name().equals(dataTypeName)) {
+      int intValue = column.getInt(rowIndex);
+      targetColumnList.add(DateUtils.formatDate(intValue));
+    } else if (TSDataType.BLOB.name().equals(dataTypeName)) {
+      byte[] v = column.getBinary(rowIndex).getValues();
+      targetColumnList.add(BytesUtils.parseBlobByteArrayToString(v));
+    } else {
+      targetColumnList.add(
+          column.getDataType().equals(TSDataType.TEXT)
+              ? 
column.getBinary(rowIndex).getStringValue(TSFileConfig.STRING_CHARSET)
+              : column.getObject(rowIndex));
+    }
+  }
+
   public static Response fillGrafanaVariablesResult(
       IQueryExecution queryExecution, Statement statement) throws 
IoTDBException {
     List<String> results = new ArrayList<>();
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/handler/QueryDataSetHandler.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/handler/QueryDataSetHandler.java
index f3f7d68dd0b..fed6e3ec80a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/handler/QueryDataSetHandler.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/handler/QueryDataSetHandler.java
@@ -34,6 +34,8 @@ import org.apache.tsfile.block.column.Column;
 import org.apache.tsfile.common.conf.TSFileConfig;
 import org.apache.tsfile.enums.TSDataType;
 import org.apache.tsfile.read.common.block.TsBlock;
+import org.apache.tsfile.utils.BytesUtils;
+import org.apache.tsfile.utils.DateUtils;
 
 import javax.ws.rs.core.Response;
 
@@ -188,10 +190,7 @@ public class QueryDataSetHandler {
           if (column.isNull(i)) {
             targetDataSetColumn.add(null);
           } else {
-            targetDataSetColumn.add(
-                column.getDataType().equals(TSDataType.TEXT)
-                    ? 
column.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET)
-                    : column.getObject(i));
+            addTypedValueToTarget(targetDataSet.getDataTypes(), k, i, 
targetDataSetColumn, column);
           }
         }
         if (k != columnNum - 1) {
@@ -210,6 +209,7 @@ public class QueryDataSetHandler {
       throws IoTDBException {
     int fetched = 0;
     int columnNum = queryExecution.getOutputValueColumnCount();
+    List<String> dataTypes = targetDataSet.getDataTypes();
     while (true) {
       if (0 < actualRowSizeLimit && actualRowSizeLimit <= fetched) {
         return Response.ok()
@@ -244,10 +244,7 @@ public class QueryDataSetHandler {
           if (column.isNull(i)) {
             targetDataSetColumn.add(null);
           } else {
-            targetDataSetColumn.add(
-                column.getDataType().equals(TSDataType.TEXT)
-                    ? 
column.getBinary(i).getStringValue(TSFileConfig.STRING_CHARSET)
-                    : column.getObject(i));
+            addTypedValueToTarget(dataTypes, k, i, targetDataSetColumn, 
column);
           }
         }
         if (k != columnNum - 1) {
@@ -258,6 +255,30 @@ public class QueryDataSetHandler {
     return Response.ok().entity(targetDataSet).build();
   }
 
+  private static void addTypedValueToTarget(
+      List<String> dataTypes,
+      int colIndex,
+      int rowIndex,
+      List<Object> targetColumnList,
+      Column column) {
+    String dataTypeName = dataTypes != null ? dataTypes.get(colIndex) : null;
+
+    if (TSDataType.TEXT.name().equals(dataTypeName)) {
+      
targetColumnList.add(column.getBinary(rowIndex).getStringValue(TSFileConfig.STRING_CHARSET));
+    } else if (TSDataType.DATE.name().equals(dataTypeName)) {
+      int intValue = column.getInt(rowIndex);
+      targetColumnList.add(DateUtils.formatDate(intValue));
+    } else if (TSDataType.BLOB.name().equals(dataTypeName)) {
+      byte[] v = column.getBinary(rowIndex).getValues();
+      targetColumnList.add(BytesUtils.parseBlobByteArrayToString(v));
+    } else {
+      targetColumnList.add(
+          column.getDataType().equals(TSDataType.TEXT)
+              ? 
column.getBinary(rowIndex).getStringValue(TSFileConfig.STRING_CHARSET)
+              : column.getObject(rowIndex));
+    }
+  }
+
   public static Response fillGrafanaVariablesResult(
       IQueryExecution queryExecution, Statement statement) throws 
IoTDBException {
     List<String> results = new ArrayList<>();
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/impl/RestApiServiceImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/impl/RestApiServiceImpl.java
index 53699256761..e9ac41f833d 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/impl/RestApiServiceImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/rest/v2/impl/RestApiServiceImpl.java
@@ -53,6 +53,7 @@ import 
org.apache.iotdb.db.queryengine.plan.parser.StatementGenerator;
 import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.TableDeviceSchemaCache;
 import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.fetcher.cache.TableId;
 import org.apache.iotdb.db.queryengine.plan.statement.Statement;
+import org.apache.iotdb.db.queryengine.plan.statement.StatementType;
 import org.apache.iotdb.db.queryengine.plan.statement.crud.InsertRowsStatement;
 import 
org.apache.iotdb.db.queryengine.plan.statement.crud.InsertTabletStatement;
 import org.apache.iotdb.db.schemaengine.SchemaEngine;
@@ -204,11 +205,13 @@ public class RestApiServiceImpl extends RestApiService {
       return 
Response.ok().entity(ExceptionHandler.tryCatchException(e)).build();
     } finally {
       long costTime = System.nanoTime() - startTime;
-      Optional.ofNullable(statement)
-          .ifPresent(
-              s ->
-                  CommonUtils.addStatementExecutionLatency(
-                      OperationType.EXECUTE_QUERY_STATEMENT, 
s.getType().name(), costTime));
+      String statementType =
+          Optional.ofNullable(statement)
+              .map(s -> s.getType().name())
+              .orElse(StatementType.FAST_LAST_QUERY.name());
+
+      CommonUtils.addStatementExecutionLatency(
+          OperationType.EXECUTE_QUERY_STATEMENT, statementType, costTime);
       if (queryId != null) {
         if (finish) {
           long executionTime = COORDINATOR.getTotalExecutionTime(queryId);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementType.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementType.java
index 4d5fe5dbf3f..748241d189b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementType.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/statement/StatementType.java
@@ -185,5 +185,7 @@ public enum StatementType {
   SHOW_SUBSCRIPTIONS,
   DROP_SUBSCRIPTION,
 
-  SET_CONFIGURATION
+  SET_CONFIGURATION,
+
+  FAST_LAST_QUERY
 }
diff --git a/iotdb-protocol/openapi/src/main/openapi3/iotdb_rest_table_v1.yaml 
b/iotdb-protocol/openapi/src/main/openapi3/iotdb_rest_table_v1.yaml
index 205174afab9..36cec631b54 100644
--- a/iotdb-protocol/openapi/src/main/openapi3/iotdb_rest_table_v1.yaml
+++ b/iotdb-protocol/openapi/src/main/openapi3/iotdb_rest_table_v1.yaml
@@ -112,7 +112,7 @@ components:
           type: array
           items:
             type: string
-        column_catogories:
+        column_categories:
           type: array
           items:
             type: string


Reply via email to