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

jackietien 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 5a25a0a46ba Implement some groupedAccumulators in TableModel
5a25a0a46ba is described below

commit 5a25a0a46ba563be95e1691a4732d534b8705e1e
Author: Weihao Li <[email protected]>
AuthorDate: Sat Oct 19 09:06:27 2024 +0800

    Implement some groupedAccumulators in TableModel
---
 .../it/query/recent/IoTDBTableAggregationIT.java   | 163 +++++----
 .../relational/aggregation/AccumulatorFactory.java |  18 +
 .../relational/aggregation/LastAccumulator.java    |   2 +-
 .../grouped/GroupedExtremeAccumulator.java         | 277 ++++++++++++++++
 .../grouped/GroupedFirstAccumulator.java           | 368 +++++++++++++++++++++
 .../grouped/GroupedLastAccumulator.java            | 368 +++++++++++++++++++++
 .../aggregation/grouped/GroupedMaxAccumulator.java | 328 ++++++++++++++++++
 .../aggregation/grouped/GroupedMinAccumulator.java | 328 ++++++++++++++++++
 .../aggregation/grouped/GroupedSumAccumulator.java | 152 +++++++++
 .../aggregation/grouped/array/BinaryBigArray.java  |  76 +++++
 .../aggregation/grouped/array/FloatBigArray.java   | 165 +++++++++
 11 files changed, 2160 insertions(+), 85 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBTableAggregationIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBTableAggregationIT.java
index af26d72746e..63b57e95ec3 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBTableAggregationIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBTableAggregationIT.java
@@ -42,71 +42,71 @@ public class IoTDBTableAggregationIT {
       new String[] {
         "CREATE DATABASE " + DATABASE_NAME,
         "USE " + DATABASE_NAME,
-        "CREATE TABLE table1(province STRING ID, city STRING ID, region STRING 
ID, device_id STRING ID, color STRING ATTRIBUTE, type STRING ATTRIBUTE, s1 
INT32 MEASUREMENT, s2 INT64 MEASUREMENT, s3 FLOAT MEASUREMENT, s4 DOUBLE 
MEASUREMENT, s5 BOOLEAN MEASUREMENT, s6 TEXT MEASUREMENT, s7 STRING 
MEASUREMENT, s8 BLOB MEASUREMENT, s9 TIMESTAMP MEASUREMENT, s10 DATE 
MEASUREMENT",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s6,s8,s9) values 
(2024-09-24T06:15:30.000+00:00,'shanghai','shanghai','huangpu','d01','red','A',30,30.0,'shanghai_huangpu_red_A_d01_30',
 X'cafebabe30',2024-09-24T06:15:30.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s3,s4,s6,s7,s9,s10) 
values 
(2024-09-24T06:15:35.000+00:00,'shanghai','shanghai','huangpu','d01','red','A',35000,35.0,35.0,'shanghai_huangpu_red_A_d01_35','shanghai_huangpu_red_A_d01_35',2024-09-24T06:15:35.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s7,s9) values 
(2024-09-24T06:15:40.000+00:00,'shanghai','shanghai','huangpu','d01','red','A',40,40.0,true,'shanghai_huangpu_red_A_d01_40',2024-09-24T06:15:40.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s5,s9,s10) values 
(2024-09-24T06:15:50.000+00:00,'shanghai','shanghai','huangpu','d01','red','A',50000,false,2024-09-24T06:15:50.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'shanghai','shanghai','huangpu','d01','red','A',55,55.0,X'cafebabe55',2024-09-24T06:15:55.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s5,s6,s7,s9) values 
(2024-09-24T06:15:36.000+00:00,'shanghai','shanghai','huangpu','d02','red','BBBBBBBBBBBBBBBB',36,true,'shanghai_huangpu_red_B_d02_36','shanghai_huangpu_red_B_d02_36',2024-09-24T06:15:36.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:40.000+00:00,'shanghai','shanghai','huangpu','d02','red','BBBBBBBBBBBBBBBB',40,40.0,'shanghai_huangpu_red_B_d02_40',2024-09-24T06:15:40.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s7,s8,s9) values 
(2024-09-24T06:15:50.000+00:00,'shanghai','shanghai','huangpu','d02','red','BBBBBBBBBBBBBBBB',50000,'shanghai_huangpu_red_B_d02_50',X'cafebabe50',2024-09-24T06:15:50.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s8,s9) values 
(2024-09-24T06:15:31.000+00:00,'shanghai','shanghai','huangpu','d03','yellow','A',31000,X'cafebabe31',2024-09-24T06:15:31.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:36.000+00:00,'shanghai','shanghai','huangpu','d03','yellow','A',36,36.0,'shanghai_huangpu_yellow_A_d03_36',2024-09-24T06:15:36.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s6,s8,s9) values 
(2024-09-24T06:15:41.000+00:00,'shanghai','shanghai','huangpu','d03','yellow','A',41,41.0,false,'shanghai_huangpu_yellow_A_d03_41',X'cafebabe41',2024-09-24T06:15:41.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s4,s7,s9) values 
(2024-09-24T06:15:46.000+00:00,'shanghai','shanghai','huangpu','d03','yellow','A',46000,46.0,'shanghai_huangpu_yellow_A_d03_46',2024-09-24T06:15:46.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s6,s9) values 
(2024-09-24T06:15:51.000+00:00,'shanghai','shanghai','huangpu','d03','yellow','A',51.0,'shanghai_huangpu_yellow_A_d03_51',2024-09-24T06:15:51.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s5,s7,s9,s10) values 
(2024-09-24T06:15:30.000+00:00,'shanghai','shanghai','huangpu','d04','yellow','BBBBBBBBBBBBBBBB',30.0,true,'shanghai_huangpu_yellow_B_d04_30',2024-09-24T06:15:30.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s9) values 
(2024-09-24T06:15:40.000+00:00,'shanghai','shanghai','huangpu','d04','yellow','BBBBBBBBBBBBBBBB',40000,2024-09-24T06:15:40.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s6,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'shanghai','shanghai','huangpu','d04','yellow','BBBBBBBBBBBBBBBB',55,55.0,'shanghai_huangpu_yellow_B_d04_55',X'cafebabe55',2024-09-24T06:15:55.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s6,s8,s9) values 
(2024-09-24T06:15:30.000+00:00,'shanghai','shanghai','pudong','d05','red','A',30,30.0,'shanghai_pudong_red_A_d05_30',
 X'cafebabe30',2024-09-24T06:15:30.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s3,s4,s6,s7,s9,s10) 
values 
(2024-09-24T06:15:35.000+00:00,'shanghai','shanghai','pudong','d05','red','A',35000,35.0,35.0,'shanghai_pudong_red_A_d05_35','shanghai_pudong_red_A_d05_35',2024-09-24T06:15:35.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s7,s9) values 
(2024-09-24T06:15:40.000+00:00,'shanghai','shanghai','pudong','d05','red','A',40,40.0,true,'shanghai_pudong_red_A_d05_40',2024-09-24T06:15:40.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s5,s9,s10) values 
(2024-09-24T06:15:50.000+00:00,'shanghai','shanghai','pudong','d05','red','A',50000,false,2024-09-24T06:15:50.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'shanghai','shanghai','pudong','d05','red','A',55,55.0,X'cafebabe55',2024-09-24T06:15:55.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s5,s6,s7,s9) values 
(2024-09-24T06:15:36.000+00:00,'shanghai','shanghai','pudong','d06','red','BBBBBBBBBBBBBBBB',36,true,'shanghai_pudong_red_B_d06_36','shanghai_pudong_red_B_d06_36',2024-09-24T06:15:36.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:40.000+00:00,'shanghai','shanghai','pudong','d06','red','BBBBBBBBBBBBBBBB',40,40.0,'shanghai_pudong_red_B_d06_40',2024-09-24T06:15:40.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s7,s8,s9) values 
(2024-09-24T06:15:50.000+00:00,'shanghai','shanghai','pudong','d06','red','BBBBBBBBBBBBBBBB',50000,'shanghai_pudong_red_B_d06_50',X'cafebabe50',2024-09-24T06:15:50.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s8,s9) values 
(2024-09-24T06:15:31.000+00:00,'shanghai','shanghai','pudong','d07','yellow','A',31000,X'cafebabe31',2024-09-24T06:15:31.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:36.000+00:00,'shanghai','shanghai','pudong','d07','yellow','A',36,36.0,'shanghai_pudong_yellow_A_d07_36',2024-09-24T06:15:36.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s6,s8,s9) values 
(2024-09-24T06:15:41.000+00:00,'shanghai','shanghai','pudong','d07','yellow','A',41,41.0,false,'shanghai_pudong_yellow_A_d07_41',X'cafebabe41',2024-09-24T06:15:41.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s4,s7,s9) values 
(2024-09-24T06:15:46.000+00:00,'shanghai','shanghai','pudong','d07','yellow','A',46000,46.0,'shanghai_pudong_yellow_A_d07_46',2024-09-24T06:15:46.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s6,s9) values 
(2024-09-24T06:15:51.000+00:00,'shanghai','shanghai','pudong','d07','yellow','A',51.0,'shanghai_pudong_yellow_A_d07_51',2024-09-24T06:15:51.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s5,s7,s9,s10) values 
(2024-09-24T06:15:30.000+00:00,'shanghai','shanghai','pudong','d08','yellow','BBBBBBBBBBBBBBBB',30.0,true,'shanghai_pudong_yellow_B_d08_30',2024-09-24T06:15:30.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s9) values 
(2024-09-24T06:15:40.000+00:00,'shanghai','shanghai','pudong','d08','yellow','BBBBBBBBBBBBBBBB',40000,2024-09-24T06:15:40.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s6,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'shanghai','shanghai','pudong','d08','yellow','BBBBBBBBBBBBBBBB',55,55.0,'shanghai_pudong_yellow_B_d08_55',X'cafebabe55',2024-09-24T06:15:55.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s6,s8,s9) values 
(2024-09-24T06:15:30.000+00:00,'beijing','beijing','chaoyang','d09','red','A',30,30.0,'beijing_chaoyang_red_A_d09_30',
 X'cafebabe30',2024-09-24T06:15:30.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s3,s4,s6,s7,s9,s10) 
values 
(2024-09-24T06:15:35.000+00:00,'beijing','beijing','chaoyang','d09','red','A',35000,35.0,35.0,'beijing_chaoyang_red_A_d09_35','beijing_chaoyang_red_A_d09_35',2024-09-24T06:15:35.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s7,s9) values 
(2024-09-24T06:15:40.000+00:00,'beijing','beijing','chaoyang','d09','red','A',40,40.0,true,'beijing_chaoyang_red_A_d09_40',2024-09-24T06:15:40.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s5,s9,s10) values 
(2024-09-24T06:15:50.000+00:00,'beijing','beijing','chaoyang','d09','red','A',50000,false,2024-09-24T06:15:50.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'beijing','beijing','chaoyang','d09','red','A',55,55.0,X'cafebabe55',2024-09-24T06:15:55.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s5,s6,s7,s9) values 
(2024-09-24T06:15:36.000+00:00,'beijing','beijing','chaoyang','d10','red','BBBBBBBBBBBBBBBB',36,true,'beijing_chaoyang_red_B_d10_36','beijing_chaoyang_red_B_d10_36',2024-09-24T06:15:36.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:40.000+00:00,'beijing','beijing','chaoyang','d10','red','BBBBBBBBBBBBBBBB',40,40.0,'beijing_chaoyang_red_B_d10_40',2024-09-24T06:15:40.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s7,s8,s9) values 
(2024-09-24T06:15:50.000+00:00,'beijing','beijing','chaoyang','d10','red','BBBBBBBBBBBBBBBB',50000,'beijing_chaoyang_red_B_d10_50',X'cafebabe50',2024-09-24T06:15:50.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s8,s9) values 
(2024-09-24T06:15:31.000+00:00,'beijing','beijing','chaoyang','d11','yellow','A',31000,X'cafebabe31',2024-09-24T06:15:31.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:36.000+00:00,'beijing','beijing','chaoyang','d11','yellow','A',36,36.0,'beijing_chaoyang_yellow_A_d11_36',2024-09-24T06:15:36.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s6,s8,s9) values 
(2024-09-24T06:15:41.000+00:00,'beijing','beijing','chaoyang','d11','yellow','A',41,41.0,false,'beijing_chaoyang_yellow_A_d11_41',X'cafebabe41',2024-09-24T06:15:41.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s4,s7,s9) values 
(2024-09-24T06:15:46.000+00:00,'beijing','beijing','chaoyang','d11','yellow','A',46000,46.0,'beijing_chaoyang_yellow_A_d11_46',2024-09-24T06:15:46.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s6,s9) values 
(2024-09-24T06:15:51.000+00:00,'beijing','beijing','chaoyang','d11','yellow','A',51.0,'beijing_chaoyang_yellow_A_d11_51',2024-09-24T06:15:51.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s5,s7,s9,s10) values 
(2024-09-24T06:15:30.000+00:00,'beijing','beijing','chaoyang','d12','yellow','BBBBBBBBBBBBBBBB',30.0,true,'beijing_chaoyang_yellow_B_d12_30',2024-09-24T06:15:30.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s9) values 
(2024-09-24T06:15:40.000+00:00,'beijing','beijing','chaoyang','d12','yellow','BBBBBBBBBBBBBBBB',40000,2024-09-24T06:15:40.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s6,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'beijing','beijing','chaoyang','d12','yellow','BBBBBBBBBBBBBBBB',55,55.0,'beijing_chaoyang_yellow_B_d12_55',X'cafebabe55',2024-09-24T06:15:55.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s6,s8,s9) values 
(2024-09-24T06:15:30.000+00:00,'beijing','beijing','haidian','d13','red','A',30,30.0,'beijing_haidian_red_A_d13_30',
 X'cafebabe30',2024-09-24T06:15:30.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s3,s4,s6,s7,s9,s10) 
values 
(2024-09-24T06:15:35.000+00:00,'beijing','beijing','haidian','d13','red','A',35000,35.0,35.0,'beijing_haidian_red_A_d13_35','beijing_haidian_red_A_d13_35',2024-09-24T06:15:35.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s7,s9) values 
(2024-09-24T06:15:40.000+00:00,'beijing','beijing','haidian','d13','red','A',40,40.0,true,'beijing_haidian_red_A_d13_40',2024-09-24T06:15:40.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s5,s9,s10) values 
(2024-09-24T06:15:50.000+00:00,'beijing','beijing','haidian','d13','red','A',50000,false,2024-09-24T06:15:50.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'beijing','beijing','haidian','d13','red','A',55,55.0,X'cafebabe55',2024-09-24T06:15:55.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s5,s6,s7,s9) values 
(2024-09-24T06:15:36.000+00:00,'beijing','beijing','haidian','d14','red','BBBBBBBBBBBBBBBB',36,true,'beijing_haidian_red_B_d14_36','beijing_haidian_red_B_d14_36',2024-09-24T06:15:36.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:40.000+00:00,'beijing','beijing','haidian','d14','red','BBBBBBBBBBBBBBBB',40,40.0,'beijing_haidian_red_B_d14_40',2024-09-24T06:15:40.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s7,s8,s9) values 
(2024-09-24T06:15:50.000+00:00,'beijing','beijing','haidian','d14','red','BBBBBBBBBBBBBBBB',50000,'beijing_haidian_red_B_d14_50',X'cafebabe50',2024-09-24T06:15:50.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s8,s9) values 
(2024-09-24T06:15:31.000+00:00,'beijing','beijing','haidian','d15','yellow','A',31000,X'cafebabe31',2024-09-24T06:15:31.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:36.000+00:00,'beijing','beijing','haidian','d15','yellow','A',36,36.0,'beijing_haidian_yellow_A_d15_36',2024-09-24T06:15:36.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s6,s8,s9) values 
(2024-09-24T06:15:41.000+00:00,'beijing','beijing','haidian','d15','yellow','A',41,41.0,false,'beijing_haidian_yellow_A_d15_41',X'cafebabe41',2024-09-24T06:15:41.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s4,s7,s9) values 
(2024-09-24T06:15:46.000+00:00,'beijing','beijing','haidian','d15','yellow','A',46000,46.0,'beijing_haidian_yellow_A_d15_46',2024-09-24T06:15:46.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s6,s9) values 
(2024-09-24T06:15:51.000+00:00,'beijing','beijing','haidian','d15','yellow','A',51.0,'beijing_haidian_yellow_A_d15_51',2024-09-24T06:15:51.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s5,s7,s9,s10) values 
(2024-09-24T06:15:30.000+00:00,'beijing','beijing','haidian','d16','yellow','BBBBBBBBBBBBBBBB',30.0,true,'beijing_haidian_yellow_B_d16_30',2024-09-24T06:15:30.000+00:00,'2024-09-24'",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s9) values 
(2024-09-24T06:15:40.000+00:00,'beijing','beijing','haidian','d16','yellow','BBBBBBBBBBBBBBBB',40000,2024-09-24T06:15:40.000+00:00",
-        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s6,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'beijing','beijing','haidian','d16','yellow','BBBBBBBBBBBBBBBB',55,55.0,'beijing_haidian_yellow_B_d16_55',X'cafebabe55',2024-09-24T06:15:55.000+00:00",
+        "CREATE TABLE table1(province STRING ID, city STRING ID, region STRING 
ID, device_id STRING ID, color STRING ATTRIBUTE, type STRING ATTRIBUTE, s1 
INT32 MEASUREMENT, s2 INT64 MEASUREMENT, s3 FLOAT MEASUREMENT, s4 DOUBLE 
MEASUREMENT, s5 BOOLEAN MEASUREMENT, s6 TEXT MEASUREMENT, s7 STRING 
MEASUREMENT, s8 BLOB MEASUREMENT, s9 TIMESTAMP MEASUREMENT, s10 DATE 
MEASUREMENT)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s6,s8,s9) values 
(2024-09-24T06:15:30.000+00:00,'shanghai','shanghai','huangpu','d01','red','A',30,30.0,'shanghai_huangpu_red_A_d01_30',
 X'cafebabe30',2024-09-24T06:15:30.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s3,s4,s6,s7,s9,s10) 
values 
(2024-09-24T06:15:35.000+00:00,'shanghai','shanghai','huangpu','d01','red','A',35000,35.0,35.0,'shanghai_huangpu_red_A_d01_35','shanghai_huangpu_red_A_d01_35',2024-09-24T06:15:35.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s7,s9) values 
(2024-09-24T06:15:40.000+00:00,'shanghai','shanghai','huangpu','d01','red','A',40,40.0,true,'shanghai_huangpu_red_A_d01_40',2024-09-24T06:15:40.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s5,s9,s10) values 
(2024-09-24T06:15:50.000+00:00,'shanghai','shanghai','huangpu','d01','red','A',50000,false,2024-09-24T06:15:50.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'shanghai','shanghai','huangpu','d01','red','A',55,55.0,X'cafebabe55',2024-09-24T06:15:55.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s5,s6,s7,s9) values 
(2024-09-24T06:15:36.000+00:00,'shanghai','shanghai','huangpu','d02','red','BBBBBBBBBBBBBBBB',36,true,'shanghai_huangpu_red_B_d02_36','shanghai_huangpu_red_B_d02_36',2024-09-24T06:15:36.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:40.000+00:00,'shanghai','shanghai','huangpu','d02','red','BBBBBBBBBBBBBBBB',40,40.0,'shanghai_huangpu_red_B_d02_40',2024-09-24T06:15:40.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s7,s8,s9) values 
(2024-09-24T06:15:50.000+00:00,'shanghai','shanghai','huangpu','d02','red','BBBBBBBBBBBBBBBB',50000,'shanghai_huangpu_red_B_d02_50',X'cafebabe50',2024-09-24T06:15:50.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s8,s9) values 
(2024-09-24T06:15:31.000+00:00,'shanghai','shanghai','huangpu','d03','yellow','A',31000,X'cafebabe31',2024-09-24T06:15:31.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:36.000+00:00,'shanghai','shanghai','huangpu','d03','yellow','A',36,36.0,'shanghai_huangpu_yellow_A_d03_36',2024-09-24T06:15:36.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s6,s8,s9) values 
(2024-09-24T06:15:41.000+00:00,'shanghai','shanghai','huangpu','d03','yellow','A',41,41.0,false,'shanghai_huangpu_yellow_A_d03_41',X'cafebabe41',2024-09-24T06:15:41.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s4,s7,s9) values 
(2024-09-24T06:15:46.000+00:00,'shanghai','shanghai','huangpu','d03','yellow','A',46000,46.0,'shanghai_huangpu_yellow_A_d03_46',2024-09-24T06:15:46.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s6,s9) values 
(2024-09-24T06:15:51.000+00:00,'shanghai','shanghai','huangpu','d03','yellow','A',51.0,'shanghai_huangpu_yellow_A_d03_51',2024-09-24T06:15:51.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s5,s7,s9,s10) values 
(2024-09-24T06:15:30.000+00:00,'shanghai','shanghai','huangpu','d04','yellow','BBBBBBBBBBBBBBBB',30.0,true,'shanghai_huangpu_yellow_B_d04_30',2024-09-24T06:15:30.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s9) values 
(2024-09-24T06:15:40.000+00:00,'shanghai','shanghai','huangpu','d04','yellow','BBBBBBBBBBBBBBBB',40000,2024-09-24T06:15:40.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s6,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'shanghai','shanghai','huangpu','d04','yellow','BBBBBBBBBBBBBBBB',55,55.0,'shanghai_huangpu_yellow_B_d04_55',X'cafebabe55',2024-09-24T06:15:55.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s6,s8,s9) values 
(2024-09-24T06:15:30.000+00:00,'shanghai','shanghai','pudong','d05','red','A',30,30.0,'shanghai_pudong_red_A_d05_30',
 X'cafebabe30',2024-09-24T06:15:30.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s3,s4,s6,s7,s9,s10) 
values 
(2024-09-24T06:15:35.000+00:00,'shanghai','shanghai','pudong','d05','red','A',35000,35.0,35.0,'shanghai_pudong_red_A_d05_35','shanghai_pudong_red_A_d05_35',2024-09-24T06:15:35.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s7,s9) values 
(2024-09-24T06:15:40.000+00:00,'shanghai','shanghai','pudong','d05','red','A',40,40.0,true,'shanghai_pudong_red_A_d05_40',2024-09-24T06:15:40.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s5,s9,s10) values 
(2024-09-24T06:15:50.000+00:00,'shanghai','shanghai','pudong','d05','red','A',50000,false,2024-09-24T06:15:50.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'shanghai','shanghai','pudong','d05','red','A',55,55.0,X'cafebabe55',2024-09-24T06:15:55.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s5,s6,s7,s9) values 
(2024-09-24T06:15:36.000+00:00,'shanghai','shanghai','pudong','d06','red','BBBBBBBBBBBBBBBB',36,true,'shanghai_pudong_red_B_d06_36','shanghai_pudong_red_B_d06_36',2024-09-24T06:15:36.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:40.000+00:00,'shanghai','shanghai','pudong','d06','red','BBBBBBBBBBBBBBBB',40,40.0,'shanghai_pudong_red_B_d06_40',2024-09-24T06:15:40.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s7,s8,s9) values 
(2024-09-24T06:15:50.000+00:00,'shanghai','shanghai','pudong','d06','red','BBBBBBBBBBBBBBBB',50000,'shanghai_pudong_red_B_d06_50',X'cafebabe50',2024-09-24T06:15:50.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s8,s9) values 
(2024-09-24T06:15:31.000+00:00,'shanghai','shanghai','pudong','d07','yellow','A',31000,X'cafebabe31',2024-09-24T06:15:31.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:36.000+00:00,'shanghai','shanghai','pudong','d07','yellow','A',36,36.0,'shanghai_pudong_yellow_A_d07_36',2024-09-24T06:15:36.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s6,s8,s9) values 
(2024-09-24T06:15:41.000+00:00,'shanghai','shanghai','pudong','d07','yellow','A',41,41.0,false,'shanghai_pudong_yellow_A_d07_41',X'cafebabe41',2024-09-24T06:15:41.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s4,s7,s9) values 
(2024-09-24T06:15:46.000+00:00,'shanghai','shanghai','pudong','d07','yellow','A',46000,46.0,'shanghai_pudong_yellow_A_d07_46',2024-09-24T06:15:46.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s6,s9) values 
(2024-09-24T06:15:51.000+00:00,'shanghai','shanghai','pudong','d07','yellow','A',51.0,'shanghai_pudong_yellow_A_d07_51',2024-09-24T06:15:51.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s5,s7,s9,s10) values 
(2024-09-24T06:15:30.000+00:00,'shanghai','shanghai','pudong','d08','yellow','BBBBBBBBBBBBBBBB',30.0,true,'shanghai_pudong_yellow_B_d08_30',2024-09-24T06:15:30.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s9) values 
(2024-09-24T06:15:40.000+00:00,'shanghai','shanghai','pudong','d08','yellow','BBBBBBBBBBBBBBBB',40000,2024-09-24T06:15:40.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s6,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'shanghai','shanghai','pudong','d08','yellow','BBBBBBBBBBBBBBBB',55,55.0,'shanghai_pudong_yellow_B_d08_55',X'cafebabe55',2024-09-24T06:15:55.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s6,s8,s9) values 
(2024-09-24T06:15:30.000+00:00,'beijing','beijing','chaoyang','d09','red','A',30,30.0,'beijing_chaoyang_red_A_d09_30',
 X'cafebabe30',2024-09-24T06:15:30.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s3,s4,s6,s7,s9,s10) 
values 
(2024-09-24T06:15:35.000+00:00,'beijing','beijing','chaoyang','d09','red','A',35000,35.0,35.0,'beijing_chaoyang_red_A_d09_35','beijing_chaoyang_red_A_d09_35',2024-09-24T06:15:35.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s7,s9) values 
(2024-09-24T06:15:40.000+00:00,'beijing','beijing','chaoyang','d09','red','A',40,40.0,true,'beijing_chaoyang_red_A_d09_40',2024-09-24T06:15:40.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s5,s9,s10) values 
(2024-09-24T06:15:50.000+00:00,'beijing','beijing','chaoyang','d09','red','A',50000,false,2024-09-24T06:15:50.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'beijing','beijing','chaoyang','d09','red','A',55,55.0,X'cafebabe55',2024-09-24T06:15:55.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s5,s6,s7,s9) values 
(2024-09-24T06:15:36.000+00:00,'beijing','beijing','chaoyang','d10','red','BBBBBBBBBBBBBBBB',36,true,'beijing_chaoyang_red_B_d10_36','beijing_chaoyang_red_B_d10_36',2024-09-24T06:15:36.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:40.000+00:00,'beijing','beijing','chaoyang','d10','red','BBBBBBBBBBBBBBBB',40,40.0,'beijing_chaoyang_red_B_d10_40',2024-09-24T06:15:40.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s7,s8,s9) values 
(2024-09-24T06:15:50.000+00:00,'beijing','beijing','chaoyang','d10','red','BBBBBBBBBBBBBBBB',50000,'beijing_chaoyang_red_B_d10_50',X'cafebabe50',2024-09-24T06:15:50.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s8,s9) values 
(2024-09-24T06:15:31.000+00:00,'beijing','beijing','chaoyang','d11','yellow','A',31000,X'cafebabe31',2024-09-24T06:15:31.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:36.000+00:00,'beijing','beijing','chaoyang','d11','yellow','A',36,36.0,'beijing_chaoyang_yellow_A_d11_36',2024-09-24T06:15:36.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s6,s8,s9) values 
(2024-09-24T06:15:41.000+00:00,'beijing','beijing','chaoyang','d11','yellow','A',41,41.0,false,'beijing_chaoyang_yellow_A_d11_41',X'cafebabe41',2024-09-24T06:15:41.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s4,s7,s9) values 
(2024-09-24T06:15:46.000+00:00,'beijing','beijing','chaoyang','d11','yellow','A',46000,46.0,'beijing_chaoyang_yellow_A_d11_46',2024-09-24T06:15:46.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s6,s9) values 
(2024-09-24T06:15:51.000+00:00,'beijing','beijing','chaoyang','d11','yellow','A',51.0,'beijing_chaoyang_yellow_A_d11_51',2024-09-24T06:15:51.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s5,s7,s9,s10) values 
(2024-09-24T06:15:30.000+00:00,'beijing','beijing','chaoyang','d12','yellow','BBBBBBBBBBBBBBBB',30.0,true,'beijing_chaoyang_yellow_B_d12_30',2024-09-24T06:15:30.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s9) values 
(2024-09-24T06:15:40.000+00:00,'beijing','beijing','chaoyang','d12','yellow','BBBBBBBBBBBBBBBB',40000,2024-09-24T06:15:40.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s6,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'beijing','beijing','chaoyang','d12','yellow','BBBBBBBBBBBBBBBB',55,55.0,'beijing_chaoyang_yellow_B_d12_55',X'cafebabe55',2024-09-24T06:15:55.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s6,s8,s9) values 
(2024-09-24T06:15:30.000+00:00,'beijing','beijing','haidian','d13','red','A',30,30.0,'beijing_haidian_red_A_d13_30',
 X'cafebabe30',2024-09-24T06:15:30.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s3,s4,s6,s7,s9,s10) 
values 
(2024-09-24T06:15:35.000+00:00,'beijing','beijing','haidian','d13','red','A',35000,35.0,35.0,'beijing_haidian_red_A_d13_35','beijing_haidian_red_A_d13_35',2024-09-24T06:15:35.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s7,s9) values 
(2024-09-24T06:15:40.000+00:00,'beijing','beijing','haidian','d13','red','A',40,40.0,true,'beijing_haidian_red_A_d13_40',2024-09-24T06:15:40.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s5,s9,s10) values 
(2024-09-24T06:15:50.000+00:00,'beijing','beijing','haidian','d13','red','A',50000,false,2024-09-24T06:15:50.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'beijing','beijing','haidian','d13','red','A',55,55.0,X'cafebabe55',2024-09-24T06:15:55.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s5,s6,s7,s9) values 
(2024-09-24T06:15:36.000+00:00,'beijing','beijing','haidian','d14','red','BBBBBBBBBBBBBBBB',36,true,'beijing_haidian_red_B_d14_36','beijing_haidian_red_B_d14_36',2024-09-24T06:15:36.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:40.000+00:00,'beijing','beijing','haidian','d14','red','BBBBBBBBBBBBBBBB',40,40.0,'beijing_haidian_red_B_d14_40',2024-09-24T06:15:40.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s7,s8,s9) values 
(2024-09-24T06:15:50.000+00:00,'beijing','beijing','haidian','d14','red','BBBBBBBBBBBBBBBB',50000,'beijing_haidian_red_B_d14_50',X'cafebabe50',2024-09-24T06:15:50.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s8,s9) values 
(2024-09-24T06:15:31.000+00:00,'beijing','beijing','haidian','d15','yellow','A',31000,X'cafebabe31',2024-09-24T06:15:31.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s7,s9,s10) values 
(2024-09-24T06:15:36.000+00:00,'beijing','beijing','haidian','d15','yellow','A',36,36.0,'beijing_haidian_yellow_A_d15_36',2024-09-24T06:15:36.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s3,s5,s6,s8,s9) values 
(2024-09-24T06:15:41.000+00:00,'beijing','beijing','haidian','d15','yellow','A',41,41.0,false,'beijing_haidian_yellow_A_d15_41',X'cafebabe41',2024-09-24T06:15:41.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s4,s7,s9) values 
(2024-09-24T06:15:46.000+00:00,'beijing','beijing','haidian','d15','yellow','A',46000,46.0,'beijing_haidian_yellow_A_d15_46',2024-09-24T06:15:46.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s6,s9) values 
(2024-09-24T06:15:51.000+00:00,'beijing','beijing','haidian','d15','yellow','A',51.0,'beijing_haidian_yellow_A_d15_51',2024-09-24T06:15:51.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s3,s5,s7,s9,s10) values 
(2024-09-24T06:15:30.000+00:00,'beijing','beijing','haidian','d16','yellow','BBBBBBBBBBBBBBBB',30.0,true,'beijing_haidian_yellow_B_d16_30',2024-09-24T06:15:30.000+00:00,'2024-09-24')",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s2,s9) values 
(2024-09-24T06:15:40.000+00:00,'beijing','beijing','haidian','d16','yellow','BBBBBBBBBBBBBBBB',40000,2024-09-24T06:15:40.000+00:00)",
+        "INSERT INTO 
table1(time,province,city,region,device_id,color,type,s1,s4,s6,s8,s9) values 
(2024-09-24T06:15:55.000+00:00,'beijing','beijing','haidian','d16','yellow','BBBBBBBBBBBBBBBB',55,55.0,'beijing_haidian_yellow_B_d16_55',X'cafebabe55',2024-09-24T06:15:55.000+00:00)",
       };
 
   @BeforeClass
@@ -120,7 +120,6 @@ public class IoTDBTableAggregationIT {
     EnvFactory.getEnv().cleanClusterEnvironment();
   }
 
-  @Ignore
   @Test
   public void countTest() {
     String[] expectedHeader = new String[] {"_col0"};
@@ -423,17 +422,15 @@ public class IoTDBTableAggregationIT {
         new String[] {
           "64,",
         };
-    tableResultSetEqualTest(
-        "select count(*) from table1;", expectedHeader, retArray, 
DATABASE_NAME);
+    tableResultSetEqualTest("select count(*) from table1", expectedHeader, 
retArray, DATABASE_NAME);
   }
 
-  @Ignore
   @Test
   public void avgTest() {
     String[] expectedHeader = new String[] {"device_id", "color", "type", 
"_col3"};
     String[] retArray =
         new String[] {
-          "d01,red,A,45.0",
+          "d01,red,A,45.0,",
         };
     tableResultSetEqualTest(
         "select device_id, color, type, avg(s4) from table1 where time >= 
2024-09-24T06:15:30.000+00:00 and time <= 2024-09-24T06:15:59.999+00:00 and 
device_id = 'd01' group by device_id, color, type",
@@ -441,10 +438,10 @@ public class IoTDBTableAggregationIT {
         retArray,
         DATABASE_NAME);
 
-    expectedHeader = new String[] {"_col0", "end_time", "device_id", "_col3"};
+    expectedHeader = new String[] {"device_id", "color", "type", "_col3"};
     retArray =
         new String[] {
-          "d01,red,A,55.0",
+          "d01,red,A,55.0,",
         };
     tableResultSetEqualTest(
         "select device_id, color, type, avg(s4) from table1 where time >= 
2024-09-24T06:15:30.000+00:00 and time <= 2024-09-24T06:15:59.999+00:00 and 
device_id = 'd01' and s1 >= 40 group by device_id, color, type",
@@ -605,16 +602,15 @@ public class IoTDBTableAggregationIT {
 
     expectedHeader = new String[] {"_col0"};
     retArray = new String[] {"44.5,"};
-    tableResultSetEqualTest("select avg(s4) from table1;", expectedHeader, 
retArray, DATABASE_NAME);
+    tableResultSetEqualTest("select avg(s4) from table1", expectedHeader, 
retArray, DATABASE_NAME);
   }
 
-  @Ignore
   @Test
   public void sumTest() {
     String[] expectedHeader = new String[] {"device_id", "color", "type", 
"_col3"};
     String[] retArray =
         new String[] {
-          "d01,red,A,90.0",
+          "d01,red,A,90.0,",
         };
     tableResultSetEqualTest(
         "select device_id, color, type, sum(s4) from table1 where time >= 
2024-09-24T06:15:30.000+00:00 and time <= 2024-09-24T06:15:59.999+00:00 and 
device_id = 'd01' group by device_id, color, type",
@@ -622,10 +618,10 @@ public class IoTDBTableAggregationIT {
         retArray,
         DATABASE_NAME);
 
-    expectedHeader = new String[] {"_col0", "end_time", "device_id", "_col3"};
+    expectedHeader = new String[] {"device_id", "color", "type", "_col3"};
     retArray =
         new String[] {
-          "d01,red,A,55.0",
+          "d01,red,A,55.0,",
         };
     tableResultSetEqualTest(
         "select device_id, color, type, sum(s4) from table1 where time >= 
2024-09-24T06:15:30.000+00:00 and time <= 2024-09-24T06:15:59.999+00:00 and 
device_id = 'd01' and s1 >= 40 group by device_id, color, type",
@@ -786,10 +782,10 @@ public class IoTDBTableAggregationIT {
 
     expectedHeader = new String[] {"_col0"};
     retArray = new String[] {"908.0,"};
-    tableResultSetEqualTest("select sum(s3) from table1;", expectedHeader, 
retArray, DATABASE_NAME);
+    // TODO Beyyes
+    tableResultSetEqualTest("select sum(s3) from table1", expectedHeader, 
retArray, DATABASE_NAME);
   }
 
-  @Ignore
   @Test
   public void minTest() {
     String[] expectedHeader =
@@ -1006,7 +1002,7 @@ public class IoTDBTableAggregationIT {
         retArray,
         DATABASE_NAME);
 
-    expectedHeader = new String[] {"province", "city", "region", "_col3"};
+    expectedHeader = new String[] {"province", "city", "region", "_col3", 
"_col4"};
     retArray =
         new String[] {
           "beijing,beijing,chaoyang,2024-09-24T06:15:30.000Z,35.0,",
@@ -1046,10 +1042,9 @@ public class IoTDBTableAggregationIT {
     expectedHeader = new String[] {"_col0", "_col1"};
     retArray = new String[] {"2024-09-24T06:15:30.000Z,30.0,"};
     tableResultSetEqualTest(
-        "select min(time),min(s3) from table1;", expectedHeader, retArray, 
DATABASE_NAME);
+        "select min(time),min(s3) from table1", expectedHeader, retArray, 
DATABASE_NAME);
   }
 
-  @Ignore
   @Test
   public void maxTest() {
     String[] expectedHeader =
@@ -1266,7 +1261,7 @@ public class IoTDBTableAggregationIT {
         retArray,
         DATABASE_NAME);
 
-    expectedHeader = new String[] {"province", "city", "region", "_col3"};
+    expectedHeader = new String[] {"province", "city", "region", "_col3", 
"_col4"};
     retArray =
         new String[] {
           "beijing,beijing,chaoyang,2024-09-24T06:15:55.000Z,55.0,",
@@ -1306,7 +1301,7 @@ public class IoTDBTableAggregationIT {
     expectedHeader = new String[] {"_col0", "_col1"};
     retArray = new String[] {"2024-09-24T06:15:55.000Z,51.0,"};
     tableResultSetEqualTest(
-        "select max(time),max(s3) from table1;", expectedHeader, retArray, 
DATABASE_NAME);
+        "select max(time),max(s3) from table1", expectedHeader, retArray, 
DATABASE_NAME);
   }
 
   @Ignore
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/AccumulatorFactory.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/AccumulatorFactory.java
index 2ae9ee40cb6..fc672796b04 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/AccumulatorFactory.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/AccumulatorFactory.java
@@ -23,6 +23,12 @@ import org.apache.iotdb.common.rpc.thrift.TAggregationType;
 import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.GroupedAccumulator;
 import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.GroupedAvgAccumulator;
 import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.GroupedCountAccumulator;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.GroupedExtremeAccumulator;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.GroupedFirstAccumulator;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.GroupedLastAccumulator;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.GroupedMaxAccumulator;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.GroupedMinAccumulator;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.GroupedSumAccumulator;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.SymbolReference;
 
@@ -98,6 +104,18 @@ public class AccumulatorFactory {
         return new GroupedCountAccumulator();
       case AVG:
         return new GroupedAvgAccumulator(inputDataTypes.get(0));
+      case SUM:
+        return new GroupedSumAccumulator(inputDataTypes.get(0));
+      case LAST:
+        return new GroupedLastAccumulator(inputDataTypes.get(0));
+      case FIRST:
+        return new GroupedFirstAccumulator(inputDataTypes.get(0));
+      case MAX:
+        return new GroupedMaxAccumulator(inputDataTypes.get(0));
+      case MIN:
+        return new GroupedMinAccumulator(inputDataTypes.get(0));
+      case EXTREME:
+        return new GroupedExtremeAccumulator(inputDataTypes.get(0));
       default:
         throw new IllegalArgumentException("Invalid Aggregation function: " + 
aggregationType);
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/LastAccumulator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/LastAccumulator.java
index 7d3b309ba5e..0a359de585a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/LastAccumulator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/LastAccumulator.java
@@ -274,7 +274,7 @@ public class LastAccumulator implements TableAccumulator {
           break;
         default:
           throw new UnSupportedDataTypeException(
-              String.format("Unsupported data type in Extreme: %s", 
seriesDataType));
+              String.format("Unsupported data type in Last: %s", 
seriesDataType));
       }
     } catch (IOException e) {
       throw new UnsupportedOperationException(
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedExtremeAccumulator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedExtremeAccumulator.java
new file mode 100644
index 00000000000..212182743ec
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedExtremeAccumulator.java
@@ -0,0 +1,277 @@
+/*
+ * 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.db.queryengine.execution.operator.source.relational.aggregation.grouped;
+
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BooleanBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.DoubleBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.FloatBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.IntBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.LongBigArray;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.read.common.block.column.BinaryColumnBuilder;
+import org.apache.tsfile.utils.RamUsageEstimator;
+import org.apache.tsfile.write.UnSupportedDataTypeException;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class GroupedExtremeAccumulator implements GroupedAccumulator {
+  private static final long INSTANCE_SIZE =
+      RamUsageEstimator.shallowSizeOfInstance(GroupedExtremeAccumulator.class);
+  private final TSDataType seriesDataType;
+
+  private final BooleanBigArray inits = new BooleanBigArray();
+
+  private LongBigArray longValues;
+  private IntBigArray intValues;
+  private FloatBigArray floatValues;
+  private DoubleBigArray doubleValues;
+
+  public GroupedExtremeAccumulator(TSDataType seriesDataType) {
+    this.seriesDataType = seriesDataType;
+    switch (seriesDataType) {
+      case INT32:
+        intValues = new IntBigArray();
+        return;
+      case INT64:
+        longValues = new LongBigArray();
+        return;
+      case FLOAT:
+        floatValues = new FloatBigArray();
+        return;
+      case DOUBLE:
+        doubleValues = new DoubleBigArray();
+        return;
+      case TEXT:
+      case STRING:
+      case BLOB:
+      case BOOLEAN:
+      case DATE:
+      case TIMESTAMP:
+      default:
+        throw new UnSupportedDataTypeException(
+            String.format("Unsupported data type : %s", seriesDataType));
+    }
+  }
+
+  @Override
+  public long getEstimatedSize() {
+    return INSTANCE_SIZE;
+  }
+
+  @Override
+  public void setGroupCount(long groupCount) {}
+
+  @Override
+  public void addInput(int[] groupIds, Column[] arguments) {
+
+    switch (seriesDataType) {
+      case INT32:
+        addIntInput(groupIds, arguments[0]);
+        return;
+      case INT64:
+        addLongInput(groupIds, arguments[0]);
+        return;
+      case FLOAT:
+        addFloatInput(groupIds, arguments[0]);
+        return;
+      case DOUBLE:
+        addDoubleInput(groupIds, arguments[0]);
+        return;
+      case TEXT:
+      case STRING:
+      case BLOB:
+      case BOOLEAN:
+      case DATE:
+      case TIMESTAMP:
+      default:
+        throw new UnSupportedDataTypeException(
+            String.format("Unsupported data type : %s", seriesDataType));
+    }
+  }
+
+  @Override
+  public void addIntermediate(int[] groupIds, Column argument) {
+
+    for (int i = 0; i < groupIds.length; i++) {
+      if (argument.isNull(i)) {
+        continue;
+      }
+
+      switch (seriesDataType) {
+        case INT32:
+          updateIntValue(groupIds[i], Math.abs(argument.getInt(i)));
+          break;
+        case INT64:
+          updateLongValue(groupIds[i], Math.abs(argument.getLong(i)));
+          break;
+        case FLOAT:
+          updateFloatValue(groupIds[i], Math.abs(argument.getFloat(i)));
+          break;
+        case DOUBLE:
+          updateDoubleValue(groupIds[i], Math.abs(argument.getDouble(i)));
+          break;
+        case TEXT:
+        case STRING:
+        case BLOB:
+        case BOOLEAN:
+        case DATE:
+        case TIMESTAMP:
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    }
+  }
+
+  @Override
+  public void evaluateIntermediate(int groupId, ColumnBuilder columnBuilder) {
+    checkArgument(
+        columnBuilder instanceof BinaryColumnBuilder,
+        "intermediate input and output of should be BinaryColumn");
+    if (!inits.get(groupId)) {
+      columnBuilder.appendNull();
+    } else {
+      switch (seriesDataType) {
+        case INT32:
+          columnBuilder.writeInt(intValues.get(groupId));
+          break;
+        case INT64:
+          columnBuilder.writeLong(longValues.get(groupId));
+          break;
+        case FLOAT:
+          columnBuilder.writeFloat(floatValues.get(groupId));
+          break;
+        case DOUBLE:
+          columnBuilder.writeDouble(doubleValues.get(groupId));
+          break;
+        case TEXT:
+        case STRING:
+        case BLOB:
+        case BOOLEAN:
+        case DATE:
+        case TIMESTAMP:
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    }
+  }
+
+  @Override
+  public void evaluateFinal(int groupId, ColumnBuilder columnBuilder) {
+    if (!inits.get(groupId)) {
+      columnBuilder.appendNull();
+    } else {
+      switch (seriesDataType) {
+        case INT32:
+          columnBuilder.writeInt(intValues.get(groupId));
+          break;
+        case INT64:
+          columnBuilder.writeLong(longValues.get(groupId));
+          break;
+        case FLOAT:
+          columnBuilder.writeFloat(floatValues.get(groupId));
+          break;
+        case DOUBLE:
+          columnBuilder.writeDouble(doubleValues.get(groupId));
+          break;
+        case TEXT:
+        case STRING:
+        case BLOB:
+        case BOOLEAN:
+        case DATE:
+        case TIMESTAMP:
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    }
+  }
+
+  @Override
+  public void prepareFinal() {}
+
+  private void addIntInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateIntValue(groupIds[i], Math.abs(valueColumn.getInt(i)));
+      }
+    }
+  }
+
+  protected void updateIntValue(int groupId, int value) {
+    int max = intValues.get(groupId);
+    if (value >= max) {
+      inits.set(groupId, true);
+      intValues.set(groupId, value);
+    }
+  }
+
+  private void addLongInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateLongValue(groupIds[i], Math.abs(valueColumn.getLong(i)));
+      }
+    }
+  }
+
+  protected void updateLongValue(int groupId, long value) {
+    long max = longValues.get(groupId);
+    if (value >= max) {
+      inits.set(groupId, true);
+      longValues.set(groupId, value);
+    }
+  }
+
+  private void addFloatInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateFloatValue(groupIds[i], Math.abs(valueColumn.getFloat(i)));
+      }
+    }
+  }
+
+  protected void updateFloatValue(int groupId, float value) {
+    float max = floatValues.get(groupId);
+    if (value >= max) {
+      inits.set(groupId, true);
+      floatValues.set(groupId, value);
+    }
+  }
+
+  private void addDoubleInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateDoubleValue(groupIds[i], Math.abs(valueColumn.getDouble(i)));
+      }
+    }
+  }
+
+  protected void updateDoubleValue(int groupId, double value) {
+    double max = doubleValues.get(groupId);
+    if (value >= max) {
+      inits.set(groupId, true);
+      doubleValues.set(groupId, value);
+    }
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedFirstAccumulator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedFirstAccumulator.java
new file mode 100644
index 00000000000..175c8c362b8
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedFirstAccumulator.java
@@ -0,0 +1,368 @@
+/*
+ * 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.db.queryengine.execution.operator.source.relational.aggregation.grouped;
+
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BinaryBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BooleanBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.DoubleBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.FloatBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.IntBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.LongBigArray;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.read.common.block.column.BinaryColumn;
+import org.apache.tsfile.read.common.block.column.BinaryColumnBuilder;
+import org.apache.tsfile.read.common.block.column.RunLengthEncodedColumn;
+import org.apache.tsfile.utils.Binary;
+import org.apache.tsfile.utils.BytesUtils;
+import org.apache.tsfile.utils.RamUsageEstimator;
+import org.apache.tsfile.write.UnSupportedDataTypeException;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class GroupedFirstAccumulator implements GroupedAccumulator {
+  private static final long INSTANCE_SIZE =
+      RamUsageEstimator.shallowSizeOfInstance(GroupedFirstAccumulator.class);
+  private final TSDataType seriesDataType;
+  private final LongBigArray minTimes = new LongBigArray(Long.MAX_VALUE);
+
+  private LongBigArray longValues;
+  private IntBigArray intValues;
+  private FloatBigArray floatValues;
+  private DoubleBigArray doubleValues;
+  private BinaryBigArray binaryValues;
+  private BooleanBigArray booleanValues;
+
+  public GroupedFirstAccumulator(TSDataType seriesDataType) {
+    this.seriesDataType = seriesDataType;
+    switch (seriesDataType) {
+      case INT32:
+      case DATE:
+        intValues = new IntBigArray();
+        return;
+      case INT64:
+      case TIMESTAMP:
+        longValues = new LongBigArray();
+        return;
+      case FLOAT:
+        floatValues = new FloatBigArray();
+        return;
+      case DOUBLE:
+        doubleValues = new DoubleBigArray();
+        return;
+      case TEXT:
+      case STRING:
+      case BLOB:
+        binaryValues = new BinaryBigArray();
+        return;
+      case BOOLEAN:
+        booleanValues = new BooleanBigArray();
+        return;
+      default:
+        throw new UnSupportedDataTypeException(
+            String.format("Unsupported data type : %s", seriesDataType));
+    }
+  }
+
+  @Override
+  public long getEstimatedSize() {
+    return INSTANCE_SIZE;
+  }
+
+  @Override
+  public void setGroupCount(long groupCount) {}
+
+  @Override
+  public void addInput(int[] groupIds, Column[] arguments) {
+    // arguments[0] is value column, arguments[1] is time column
+    switch (seriesDataType) {
+      case INT32:
+      case DATE:
+        addIntInput(groupIds, arguments[0], arguments[1]);
+        return;
+      case INT64:
+      case TIMESTAMP:
+        addLongInput(groupIds, arguments[0], arguments[1]);
+        return;
+      case FLOAT:
+        addFloatInput(groupIds, arguments[0], arguments[1]);
+        return;
+      case DOUBLE:
+        addDoubleInput(groupIds, arguments[0], arguments[1]);
+        return;
+      case TEXT:
+      case STRING:
+      case BLOB:
+        addBinaryInput(groupIds, arguments[0], arguments[1]);
+        return;
+      case BOOLEAN:
+        addBooleanInput(groupIds, arguments[0], arguments[1]);
+        return;
+      default:
+        throw new UnSupportedDataTypeException(
+            String.format("Unsupported data type : %s", seriesDataType));
+    }
+  }
+
+  @Override
+  public void addIntermediate(int[] groupIds, Column argument) {
+    checkArgument(
+        argument instanceof BinaryColumn || argument instanceof 
RunLengthEncodedColumn,
+        "intermediate input and output should be BinaryColumn");
+
+    for (int i = 0; i < groupIds.length; i++) {
+      if (argument.isNull(i)) {
+        continue;
+      }
+
+      byte[] bytes = argument.getBinary(i).getValues();
+      long time = BytesUtils.bytesToLongFromOffset(bytes, Long.BYTES, 0);
+      int offset = Long.BYTES;
+
+      switch (seriesDataType) {
+        case INT32:
+        case DATE:
+          int intVal = BytesUtils.bytesToInt(bytes, offset);
+          updateIntValue(groupIds[i], intVal, time);
+          break;
+        case INT64:
+        case TIMESTAMP:
+          long longVal = BytesUtils.bytesToLongFromOffset(bytes, Long.BYTES, 
offset);
+          updateLongValue(groupIds[i], longVal, time);
+          break;
+        case FLOAT:
+          float floatVal = BytesUtils.bytesToFloat(bytes, offset);
+          updateFloatValue(groupIds[i], floatVal, time);
+          break;
+        case DOUBLE:
+          double doubleVal = BytesUtils.bytesToDouble(bytes, offset);
+          updateDoubleValue(groupIds[i], doubleVal, time);
+          break;
+        case TEXT:
+        case BLOB:
+        case STRING:
+          int length = BytesUtils.bytesToInt(bytes, offset);
+          offset += Integer.BYTES;
+          Binary binaryVal = new Binary(BytesUtils.subBytes(bytes, offset, 
length));
+          updateBinaryValue(groupIds[i], binaryVal, time);
+          break;
+        case BOOLEAN:
+          boolean boolVal = BytesUtils.bytesToBool(bytes, offset);
+          updateBooleanValue(groupIds[i], boolVal, time);
+          break;
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    }
+  }
+
+  @Override
+  public void evaluateIntermediate(int groupId, ColumnBuilder columnBuilder) {
+    checkArgument(
+        columnBuilder instanceof BinaryColumnBuilder,
+        "intermediate input and output of should be BinaryColumn");
+    if (minTimes.get(groupId) == Long.MIN_VALUE) {
+      columnBuilder.appendNull();
+    } else {
+      columnBuilder.writeBinary(new Binary(serializeTimeWithValue(groupId)));
+    }
+  }
+
+  @Override
+  public void evaluateFinal(int groupId, ColumnBuilder columnBuilder) {
+    if (minTimes.get(groupId) == Long.MIN_VALUE) {
+      columnBuilder.appendNull();
+    } else {
+      switch (seriesDataType) {
+        case INT32:
+        case DATE:
+          columnBuilder.writeInt(intValues.get(groupId));
+          break;
+        case INT64:
+        case TIMESTAMP:
+          columnBuilder.writeLong(longValues.get(groupId));
+          break;
+        case FLOAT:
+          columnBuilder.writeFloat(floatValues.get(groupId));
+          break;
+        case DOUBLE:
+          columnBuilder.writeDouble(doubleValues.get(groupId));
+          break;
+        case TEXT:
+        case BLOB:
+        case STRING:
+          columnBuilder.writeBinary(binaryValues.get(groupId));
+          break;
+        case BOOLEAN:
+          columnBuilder.writeBoolean(booleanValues.get(groupId));
+          break;
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    }
+  }
+
+  @Override
+  public void prepareFinal() {}
+
+  private byte[] serializeTimeWithValue(int groupId) {
+    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+    DataOutputStream dataOutputStream = new 
DataOutputStream(byteArrayOutputStream);
+    try {
+      dataOutputStream.writeLong(minTimes.get(groupId));
+      switch (seriesDataType) {
+        case INT32:
+        case DATE:
+          dataOutputStream.writeInt(intValues.get(groupId));
+          break;
+        case INT64:
+        case TIMESTAMP:
+          dataOutputStream.writeLong(longValues.get(groupId));
+          break;
+        case FLOAT:
+          dataOutputStream.writeFloat(floatValues.get(groupId));
+          break;
+        case DOUBLE:
+          dataOutputStream.writeDouble(doubleValues.get(groupId));
+          break;
+        case TEXT:
+        case BLOB:
+        case STRING:
+          byte[] values = binaryValues.get(groupId).getValues();
+          dataOutputStream.writeInt(values.length);
+          dataOutputStream.write(values);
+          break;
+        case BOOLEAN:
+          dataOutputStream.writeBoolean(booleanValues.get(groupId));
+          break;
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    } catch (IOException e) {
+      throw new UnsupportedOperationException("Failed to serialize 
intermediate result.", e);
+    }
+    return byteArrayOutputStream.toByteArray();
+  }
+
+  private void addIntInput(int[] groupIds, Column valueColumn, Column 
timeColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateIntValue(groupIds[i], valueColumn.getInt(i), 
timeColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateIntValue(int groupId, int value, long curTime) {
+    long minTime = minTimes.get(groupId);
+    if (curTime < minTime) {
+      minTimes.set(groupId, curTime);
+      intValues.set(groupId, value);
+    }
+  }
+
+  private void addLongInput(int[] groupIds, Column valueColumn, Column 
timeColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateLongValue(groupIds[i], valueColumn.getLong(i), 
timeColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateLongValue(int groupId, long value, long curTime) {
+    long minTime = minTimes.get(groupId);
+    if (curTime < minTime) {
+      minTimes.set(groupId, curTime);
+      longValues.set(groupId, value);
+    }
+  }
+
+  private void addFloatInput(int[] groupIds, Column valueColumn, Column 
timeColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateFloatValue(groupIds[i], valueColumn.getFloat(i), 
timeColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateFloatValue(int groupId, float value, long curTime) {
+    long minTime = minTimes.get(groupId);
+    if (curTime < minTime) {
+      minTimes.set(groupId, curTime);
+      floatValues.set(groupId, value);
+    }
+  }
+
+  private void addDoubleInput(int[] groupIds, Column valueColumn, Column 
timeColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateDoubleValue(groupIds[i], valueColumn.getDouble(i), 
timeColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateDoubleValue(int groupId, double value, long curTime) {
+    long minTime = minTimes.get(groupId);
+    if (curTime < minTime) {
+      minTimes.set(groupId, curTime);
+      doubleValues.set(groupId, value);
+    }
+  }
+
+  private void addBinaryInput(int[] groupIds, Column valueColumn, Column 
timeColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateBinaryValue(groupIds[i], valueColumn.getBinary(i), 
timeColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateBinaryValue(int groupId, Binary value, long curTime) {
+    long minTime = minTimes.get(groupId);
+    if (curTime < minTime) {
+      minTimes.set(groupId, curTime);
+      binaryValues.set(groupId, value);
+    }
+  }
+
+  private void addBooleanInput(int[] groupIds, Column valueColumn, Column 
timeColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateBooleanValue(groupIds[i], valueColumn.getBoolean(i), 
timeColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateBooleanValue(int groupId, boolean value, long curTime) {
+    long minTime = minTimes.get(groupId);
+    if (curTime < minTime) {
+      minTimes.set(groupId, curTime);
+      booleanValues.set(groupId, value);
+    }
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedLastAccumulator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedLastAccumulator.java
new file mode 100644
index 00000000000..2ad3c3eb30d
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedLastAccumulator.java
@@ -0,0 +1,368 @@
+/*
+ * 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.db.queryengine.execution.operator.source.relational.aggregation.grouped;
+
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BinaryBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BooleanBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.DoubleBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.FloatBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.IntBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.LongBigArray;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.read.common.block.column.BinaryColumn;
+import org.apache.tsfile.read.common.block.column.BinaryColumnBuilder;
+import org.apache.tsfile.read.common.block.column.RunLengthEncodedColumn;
+import org.apache.tsfile.utils.Binary;
+import org.apache.tsfile.utils.BytesUtils;
+import org.apache.tsfile.utils.RamUsageEstimator;
+import org.apache.tsfile.write.UnSupportedDataTypeException;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class GroupedLastAccumulator implements GroupedAccumulator {
+  private static final long INSTANCE_SIZE =
+      RamUsageEstimator.shallowSizeOfInstance(GroupedLastAccumulator.class);
+  private final TSDataType seriesDataType;
+  private final LongBigArray maxTimes = new LongBigArray(Long.MIN_VALUE);
+
+  private LongBigArray longValues;
+  private IntBigArray intValues;
+  private FloatBigArray floatValues;
+  private DoubleBigArray doubleValues;
+  private BinaryBigArray binaryValues;
+  private BooleanBigArray booleanValues;
+
+  public GroupedLastAccumulator(TSDataType seriesDataType) {
+    this.seriesDataType = seriesDataType;
+    switch (seriesDataType) {
+      case INT32:
+      case DATE:
+        intValues = new IntBigArray();
+        return;
+      case INT64:
+      case TIMESTAMP:
+        longValues = new LongBigArray();
+        return;
+      case FLOAT:
+        floatValues = new FloatBigArray();
+        return;
+      case DOUBLE:
+        doubleValues = new DoubleBigArray();
+        return;
+      case TEXT:
+      case STRING:
+      case BLOB:
+        binaryValues = new BinaryBigArray();
+        return;
+      case BOOLEAN:
+        booleanValues = new BooleanBigArray();
+        return;
+      default:
+        throw new UnSupportedDataTypeException(
+            String.format("Unsupported data type in : %s", seriesDataType));
+    }
+  }
+
+  @Override
+  public long getEstimatedSize() {
+    return INSTANCE_SIZE;
+  }
+
+  @Override
+  public void setGroupCount(long groupCount) {}
+
+  @Override
+  public void addInput(int[] groupIds, Column[] arguments) {
+    // arguments[0] is value column, arguments[1] is time column
+    switch (seriesDataType) {
+      case INT32:
+      case DATE:
+        addIntInput(groupIds, arguments[0], arguments[1]);
+        return;
+      case INT64:
+      case TIMESTAMP:
+        addLongInput(groupIds, arguments[0], arguments[1]);
+        return;
+      case FLOAT:
+        addFloatInput(groupIds, arguments[0], arguments[1]);
+        return;
+      case DOUBLE:
+        addDoubleInput(groupIds, arguments[0], arguments[1]);
+        return;
+      case TEXT:
+      case STRING:
+      case BLOB:
+        addBinaryInput(groupIds, arguments[0], arguments[1]);
+        return;
+      case BOOLEAN:
+        addBooleanInput(groupIds, arguments[0], arguments[1]);
+        return;
+      default:
+        throw new UnSupportedDataTypeException(
+            String.format("Unsupported data type : %s", seriesDataType));
+    }
+  }
+
+  @Override
+  public void addIntermediate(int[] groupIds, Column argument) {
+    checkArgument(
+        argument instanceof BinaryColumn || argument instanceof 
RunLengthEncodedColumn,
+        "intermediate input and output should be BinaryColumn");
+
+    for (int i = 0; i < groupIds.length; i++) {
+      if (argument.isNull(i)) {
+        continue;
+      }
+
+      byte[] bytes = argument.getBinary(i).getValues();
+      long time = BytesUtils.bytesToLongFromOffset(bytes, Long.BYTES, 0);
+      int offset = Long.BYTES;
+
+      switch (seriesDataType) {
+        case INT32:
+        case DATE:
+          int intVal = BytesUtils.bytesToInt(bytes, offset);
+          updateIntValue(groupIds[i], intVal, time);
+          break;
+        case INT64:
+        case TIMESTAMP:
+          long longVal = BytesUtils.bytesToLongFromOffset(bytes, Long.BYTES, 
offset);
+          updateLongValue(groupIds[i], longVal, time);
+          break;
+        case FLOAT:
+          float floatVal = BytesUtils.bytesToFloat(bytes, offset);
+          updateFloatValue(groupIds[i], floatVal, time);
+          break;
+        case DOUBLE:
+          double doubleVal = BytesUtils.bytesToDouble(bytes, offset);
+          updateDoubleValue(groupIds[i], doubleVal, time);
+          break;
+        case TEXT:
+        case BLOB:
+        case STRING:
+          int length = BytesUtils.bytesToInt(bytes, offset);
+          offset += Integer.BYTES;
+          Binary binaryVal = new Binary(BytesUtils.subBytes(bytes, offset, 
length));
+          updateBinaryValue(groupIds[i], binaryVal, time);
+          break;
+        case BOOLEAN:
+          boolean boolVal = BytesUtils.bytesToBool(bytes, offset);
+          updateBooleanValue(groupIds[i], boolVal, time);
+          break;
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type Aggregation: %s", 
seriesDataType));
+      }
+    }
+  }
+
+  @Override
+  public void evaluateIntermediate(int groupId, ColumnBuilder columnBuilder) {
+    checkArgument(
+        columnBuilder instanceof BinaryColumnBuilder,
+        "intermediate input and output of should be BinaryColumn");
+    if (maxTimes.get(groupId) == Long.MIN_VALUE) {
+      columnBuilder.appendNull();
+    } else {
+      columnBuilder.writeBinary(new Binary(serializeTimeWithValue(groupId)));
+    }
+  }
+
+  @Override
+  public void evaluateFinal(int groupId, ColumnBuilder columnBuilder) {
+    if (maxTimes.get(groupId) == Long.MIN_VALUE) {
+      columnBuilder.appendNull();
+    } else {
+      switch (seriesDataType) {
+        case INT32:
+        case DATE:
+          columnBuilder.writeInt(intValues.get(groupId));
+          break;
+        case INT64:
+        case TIMESTAMP:
+          columnBuilder.writeLong(longValues.get(groupId));
+          break;
+        case FLOAT:
+          columnBuilder.writeFloat(floatValues.get(groupId));
+          break;
+        case DOUBLE:
+          columnBuilder.writeDouble(doubleValues.get(groupId));
+          break;
+        case TEXT:
+        case BLOB:
+        case STRING:
+          columnBuilder.writeBinary(binaryValues.get(groupId));
+          break;
+        case BOOLEAN:
+          columnBuilder.writeBoolean(booleanValues.get(groupId));
+          break;
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    }
+  }
+
+  @Override
+  public void prepareFinal() {}
+
+  private byte[] serializeTimeWithValue(int groupId) {
+    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+    DataOutputStream dataOutputStream = new 
DataOutputStream(byteArrayOutputStream);
+    try {
+      dataOutputStream.writeLong(maxTimes.get(groupId));
+      switch (seriesDataType) {
+        case INT32:
+        case DATE:
+          dataOutputStream.writeInt(intValues.get(groupId));
+          break;
+        case INT64:
+        case TIMESTAMP:
+          dataOutputStream.writeLong(longValues.get(groupId));
+          break;
+        case FLOAT:
+          dataOutputStream.writeFloat(floatValues.get(groupId));
+          break;
+        case DOUBLE:
+          dataOutputStream.writeDouble(doubleValues.get(groupId));
+          break;
+        case TEXT:
+        case BLOB:
+        case STRING:
+          byte[] values = binaryValues.get(groupId).getValues();
+          dataOutputStream.writeInt(values.length);
+          dataOutputStream.write(values);
+          break;
+        case BOOLEAN:
+          dataOutputStream.writeBoolean(booleanValues.get(groupId));
+          break;
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    } catch (IOException e) {
+      throw new UnsupportedOperationException("Failed to serialize 
intermediate result.", e);
+    }
+    return byteArrayOutputStream.toByteArray();
+  }
+
+  private void addIntInput(int[] groupIds, Column valueColumn, Column 
timeColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateIntValue(groupIds[i], valueColumn.getInt(i), 
timeColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateIntValue(int groupId, int value, long curTime) {
+    long maxTime = maxTimes.get(groupId);
+    if (curTime > maxTime) {
+      maxTimes.set(groupId, curTime);
+      intValues.set(groupId, value);
+    }
+  }
+
+  private void addLongInput(int[] groupIds, Column valueColumn, Column 
timeColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateLongValue(groupIds[i], valueColumn.getLong(i), 
timeColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateLongValue(int groupId, long value, long curTime) {
+    long maxTime = maxTimes.get(groupId);
+    if (curTime > maxTime) {
+      maxTimes.set(groupId, curTime);
+      longValues.set(groupId, value);
+    }
+  }
+
+  private void addFloatInput(int[] groupIds, Column valueColumn, Column 
timeColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateFloatValue(groupIds[i], valueColumn.getFloat(i), 
timeColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateFloatValue(int groupId, float value, long curTime) {
+    long maxTime = maxTimes.get(groupId);
+    if (curTime > maxTime) {
+      maxTimes.set(groupId, curTime);
+      floatValues.set(groupId, value);
+    }
+  }
+
+  private void addDoubleInput(int[] groupIds, Column valueColumn, Column 
timeColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateDoubleValue(groupIds[i], valueColumn.getDouble(i), 
timeColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateDoubleValue(int groupId, double value, long curTime) {
+    long maxTime = maxTimes.get(groupId);
+    if (curTime > maxTime) {
+      maxTimes.set(groupId, curTime);
+      doubleValues.set(groupId, value);
+    }
+  }
+
+  private void addBinaryInput(int[] groupIds, Column valueColumn, Column 
timeColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateBinaryValue(groupIds[i], valueColumn.getBinary(i), 
timeColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateBinaryValue(int groupId, Binary value, long curTime) {
+    long maxTime = maxTimes.get(groupId);
+    if (curTime > maxTime) {
+      maxTimes.set(groupId, curTime);
+      binaryValues.set(groupId, value);
+    }
+  }
+
+  private void addBooleanInput(int[] groupIds, Column valueColumn, Column 
timeColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateBooleanValue(groupIds[i], valueColumn.getBoolean(i), 
timeColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateBooleanValue(int groupId, boolean value, long curTime) {
+    long maxTime = maxTimes.get(groupId);
+    if (curTime > maxTime) {
+      maxTimes.set(groupId, curTime);
+      booleanValues.set(groupId, value);
+    }
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedMaxAccumulator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedMaxAccumulator.java
new file mode 100644
index 00000000000..381ea71bf7d
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedMaxAccumulator.java
@@ -0,0 +1,328 @@
+/*
+ * 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.db.queryengine.execution.operator.source.relational.aggregation.grouped;
+
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BinaryBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BooleanBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.DoubleBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.FloatBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.IntBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.LongBigArray;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.utils.Binary;
+import org.apache.tsfile.utils.RamUsageEstimator;
+import org.apache.tsfile.write.UnSupportedDataTypeException;
+
+public class GroupedMaxAccumulator implements GroupedAccumulator {
+  private static final long INSTANCE_SIZE =
+      RamUsageEstimator.shallowSizeOfInstance(GroupedMaxAccumulator.class);
+  private final TSDataType seriesDataType;
+
+  private final BooleanBigArray inits = new BooleanBigArray();
+
+  private LongBigArray longValues;
+  private IntBigArray intValues;
+  private FloatBigArray floatValues;
+  private DoubleBigArray doubleValues;
+  private BinaryBigArray binaryValues;
+  private BooleanBigArray booleanValues;
+
+  public GroupedMaxAccumulator(TSDataType seriesDataType) {
+    this.seriesDataType = seriesDataType;
+    switch (seriesDataType) {
+      case INT32:
+      case DATE:
+        // Use MIN_VALUE to init NumericType to optimize updateValue method
+        intValues = new IntBigArray(Integer.MIN_VALUE);
+        return;
+      case INT64:
+      case TIMESTAMP:
+        longValues = new LongBigArray(Long.MIN_VALUE);
+        return;
+      case FLOAT:
+        floatValues = new FloatBigArray(Float.MIN_VALUE);
+        return;
+      case DOUBLE:
+        doubleValues = new DoubleBigArray(Double.MIN_VALUE);
+        return;
+      case TEXT:
+      case STRING:
+      case BLOB:
+        binaryValues = new BinaryBigArray();
+        return;
+      case BOOLEAN:
+        booleanValues = new BooleanBigArray();
+        return;
+      default:
+        throw new UnSupportedDataTypeException(
+            String.format("Unsupported data type : %s", seriesDataType));
+    }
+  }
+
+  @Override
+  public long getEstimatedSize() {
+    return INSTANCE_SIZE;
+  }
+
+  @Override
+  public void setGroupCount(long groupCount) {}
+
+  @Override
+  public void addInput(int[] groupIds, Column[] arguments) {
+
+    switch (seriesDataType) {
+      case INT32:
+      case DATE:
+        addIntInput(groupIds, arguments[0]);
+        return;
+      case INT64:
+      case TIMESTAMP:
+        addLongInput(groupIds, arguments[0]);
+        return;
+      case FLOAT:
+        addFloatInput(groupIds, arguments[0]);
+        return;
+      case DOUBLE:
+        addDoubleInput(groupIds, arguments[0]);
+        return;
+      case TEXT:
+      case STRING:
+      case BLOB:
+        addBinaryInput(groupIds, arguments[0]);
+        return;
+      case BOOLEAN:
+        addBooleanInput(groupIds, arguments[0]);
+        return;
+      default:
+        throw new UnSupportedDataTypeException(
+            String.format("Unsupported data type : %s", seriesDataType));
+    }
+  }
+
+  @Override
+  public void addIntermediate(int[] groupIds, Column argument) {
+
+    for (int i = 0; i < groupIds.length; i++) {
+      if (argument.isNull(i)) {
+        continue;
+      }
+
+      switch (seriesDataType) {
+        case INT32:
+        case DATE:
+          updateIntValue(groupIds[i], argument.getInt(i));
+          break;
+        case INT64:
+        case TIMESTAMP:
+          updateLongValue(groupIds[i], argument.getLong(i));
+          break;
+        case FLOAT:
+          updateFloatValue(groupIds[i], argument.getFloat(i));
+          break;
+        case DOUBLE:
+          updateDoubleValue(groupIds[i], argument.getDouble(i));
+          break;
+        case TEXT:
+        case BLOB:
+        case STRING:
+          updateBinaryValue(groupIds[i], argument.getBinary(i));
+          break;
+        case BOOLEAN:
+          updateBooleanValue(groupIds[i], argument.getBoolean(i));
+          break;
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    }
+  }
+
+  @Override
+  public void evaluateIntermediate(int groupId, ColumnBuilder columnBuilder) {
+
+    if (!inits.get(groupId)) {
+      columnBuilder.appendNull();
+    } else {
+      switch (seriesDataType) {
+        case INT32:
+        case DATE:
+          columnBuilder.writeInt(intValues.get(groupId));
+          break;
+        case INT64:
+        case TIMESTAMP:
+          columnBuilder.writeLong(longValues.get(groupId));
+          break;
+        case FLOAT:
+          columnBuilder.writeFloat(floatValues.get(groupId));
+          break;
+        case DOUBLE:
+          columnBuilder.writeDouble(doubleValues.get(groupId));
+          break;
+        case TEXT:
+        case BLOB:
+        case STRING:
+          columnBuilder.writeBinary(binaryValues.get(groupId));
+          break;
+        case BOOLEAN:
+          columnBuilder.writeBoolean(booleanValues.get(groupId));
+          break;
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    }
+  }
+
+  @Override
+  public void evaluateFinal(int groupId, ColumnBuilder columnBuilder) {
+    if (!inits.get(groupId)) {
+      columnBuilder.appendNull();
+    } else {
+      switch (seriesDataType) {
+        case INT32:
+        case DATE:
+          columnBuilder.writeInt(intValues.get(groupId));
+          break;
+        case INT64:
+        case TIMESTAMP:
+          columnBuilder.writeLong(longValues.get(groupId));
+          break;
+        case FLOAT:
+          columnBuilder.writeFloat(floatValues.get(groupId));
+          break;
+        case DOUBLE:
+          columnBuilder.writeDouble(doubleValues.get(groupId));
+          break;
+        case TEXT:
+        case BLOB:
+        case STRING:
+          columnBuilder.writeBinary(binaryValues.get(groupId));
+          break;
+        case BOOLEAN:
+          columnBuilder.writeBoolean(booleanValues.get(groupId));
+          break;
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    }
+  }
+
+  @Override
+  public void prepareFinal() {}
+
+  private void addIntInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateIntValue(groupIds[i], valueColumn.getInt(i));
+      }
+    }
+  }
+
+  protected void updateIntValue(int groupId, int value) {
+    int max = intValues.get(groupId);
+    if (value >= max) {
+      inits.set(groupId, true);
+      intValues.set(groupId, value);
+    }
+  }
+
+  private void addLongInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateLongValue(groupIds[i], valueColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateLongValue(int groupId, long value) {
+    long max = longValues.get(groupId);
+    if (value >= max) {
+      inits.set(groupId, true);
+      longValues.set(groupId, value);
+    }
+  }
+
+  private void addFloatInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateFloatValue(groupIds[i], valueColumn.getFloat(i));
+      }
+    }
+  }
+
+  protected void updateFloatValue(int groupId, float value) {
+    float max = floatValues.get(groupId);
+    if (value >= max) {
+      inits.set(groupId, true);
+      floatValues.set(groupId, value);
+    }
+  }
+
+  private void addDoubleInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateDoubleValue(groupIds[i], valueColumn.getDouble(i));
+      }
+    }
+  }
+
+  protected void updateDoubleValue(int groupId, double value) {
+    double max = doubleValues.get(groupId);
+    if (value >= max) {
+      inits.set(groupId, true);
+      doubleValues.set(groupId, value);
+    }
+  }
+
+  private void addBinaryInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateBinaryValue(groupIds[i], valueColumn.getBinary(i));
+      }
+    }
+  }
+
+  protected void updateBinaryValue(int groupId, Binary value) {
+    Binary max = binaryValues.get(groupId);
+    if (!inits.get(groupId) || value.compareTo(max) > 0) {
+      inits.set(groupId, true);
+      binaryValues.set(groupId, value);
+    }
+  }
+
+  private void addBooleanInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateBooleanValue(groupIds[i], valueColumn.getBoolean(i));
+      }
+    }
+  }
+
+  protected void updateBooleanValue(int groupId, boolean value) {
+    if (!inits.get(groupId) || value) {
+      inits.set(groupId, true);
+      booleanValues.set(groupId, value);
+    }
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedMinAccumulator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedMinAccumulator.java
new file mode 100644
index 00000000000..06ae08636a7
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedMinAccumulator.java
@@ -0,0 +1,328 @@
+/*
+ * 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.db.queryengine.execution.operator.source.relational.aggregation.grouped;
+
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BinaryBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BooleanBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.DoubleBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.FloatBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.IntBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.LongBigArray;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.utils.Binary;
+import org.apache.tsfile.utils.RamUsageEstimator;
+import org.apache.tsfile.write.UnSupportedDataTypeException;
+
+public class GroupedMinAccumulator implements GroupedAccumulator {
+  private static final long INSTANCE_SIZE =
+      RamUsageEstimator.shallowSizeOfInstance(GroupedMinAccumulator.class);
+  private final TSDataType seriesDataType;
+
+  private final BooleanBigArray inits = new BooleanBigArray();
+
+  private LongBigArray longValues;
+  private IntBigArray intValues;
+  private FloatBigArray floatValues;
+  private DoubleBigArray doubleValues;
+  private BinaryBigArray binaryValues;
+  private BooleanBigArray booleanValues;
+
+  public GroupedMinAccumulator(TSDataType seriesDataType) {
+    this.seriesDataType = seriesDataType;
+    switch (seriesDataType) {
+      case INT32:
+      case DATE:
+        // Use MAX_VALUE to init NumericType to optimize updateValue method
+        intValues = new IntBigArray(Integer.MAX_VALUE);
+        return;
+      case INT64:
+      case TIMESTAMP:
+        longValues = new LongBigArray(Long.MAX_VALUE);
+        return;
+      case FLOAT:
+        floatValues = new FloatBigArray(Float.MAX_VALUE);
+        return;
+      case DOUBLE:
+        doubleValues = new DoubleBigArray(Double.MAX_VALUE);
+        return;
+      case TEXT:
+      case STRING:
+      case BLOB:
+        binaryValues = new BinaryBigArray();
+        return;
+      case BOOLEAN:
+        booleanValues = new BooleanBigArray();
+        return;
+      default:
+        throw new UnSupportedDataTypeException(
+            String.format("Unsupported data type : %s", seriesDataType));
+    }
+  }
+
+  @Override
+  public long getEstimatedSize() {
+    return INSTANCE_SIZE;
+  }
+
+  @Override
+  public void setGroupCount(long groupCount) {}
+
+  @Override
+  public void addInput(int[] groupIds, Column[] arguments) {
+
+    switch (seriesDataType) {
+      case INT32:
+      case DATE:
+        addIntInput(groupIds, arguments[0]);
+        return;
+      case INT64:
+      case TIMESTAMP:
+        addLongInput(groupIds, arguments[0]);
+        return;
+      case FLOAT:
+        addFloatInput(groupIds, arguments[0]);
+        return;
+      case DOUBLE:
+        addDoubleInput(groupIds, arguments[0]);
+        return;
+      case TEXT:
+      case STRING:
+      case BLOB:
+        addBinaryInput(groupIds, arguments[0]);
+        return;
+      case BOOLEAN:
+        addBooleanInput(groupIds, arguments[0]);
+        return;
+      default:
+        throw new UnSupportedDataTypeException(
+            String.format("Unsupported data type : %s", seriesDataType));
+    }
+  }
+
+  @Override
+  public void addIntermediate(int[] groupIds, Column argument) {
+
+    for (int i = 0; i < groupIds.length; i++) {
+      if (argument.isNull(i)) {
+        continue;
+      }
+
+      switch (seriesDataType) {
+        case INT32:
+        case DATE:
+          updateIntValue(groupIds[i], argument.getInt(i));
+          break;
+        case INT64:
+        case TIMESTAMP:
+          updateLongValue(groupIds[i], argument.getLong(i));
+          break;
+        case FLOAT:
+          updateFloatValue(groupIds[i], argument.getFloat(i));
+          break;
+        case DOUBLE:
+          updateDoubleValue(groupIds[i], argument.getDouble(i));
+          break;
+        case TEXT:
+        case BLOB:
+        case STRING:
+          updateBinaryValue(groupIds[i], argument.getBinary(i));
+          break;
+        case BOOLEAN:
+          updateBooleanValue(groupIds[i], argument.getBoolean(i));
+          break;
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    }
+  }
+
+  @Override
+  public void evaluateIntermediate(int groupId, ColumnBuilder columnBuilder) {
+
+    if (!inits.get(groupId)) {
+      columnBuilder.appendNull();
+    } else {
+      switch (seriesDataType) {
+        case INT32:
+        case DATE:
+          columnBuilder.writeInt(intValues.get(groupId));
+          break;
+        case INT64:
+        case TIMESTAMP:
+          columnBuilder.writeLong(longValues.get(groupId));
+          break;
+        case FLOAT:
+          columnBuilder.writeFloat(floatValues.get(groupId));
+          break;
+        case DOUBLE:
+          columnBuilder.writeDouble(doubleValues.get(groupId));
+          break;
+        case STRING:
+        case TEXT:
+        case BLOB:
+          columnBuilder.writeBinary(binaryValues.get(groupId));
+          break;
+        case BOOLEAN:
+          columnBuilder.writeBoolean(booleanValues.get(groupId));
+          break;
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    }
+  }
+
+  @Override
+  public void evaluateFinal(int groupId, ColumnBuilder columnBuilder) {
+    if (!inits.get(groupId)) {
+      columnBuilder.appendNull();
+    } else {
+      switch (seriesDataType) {
+        case INT32:
+        case DATE:
+          columnBuilder.writeInt(intValues.get(groupId));
+          break;
+        case INT64:
+        case TIMESTAMP:
+          columnBuilder.writeLong(longValues.get(groupId));
+          break;
+        case FLOAT:
+          columnBuilder.writeFloat(floatValues.get(groupId));
+          break;
+        case DOUBLE:
+          columnBuilder.writeDouble(doubleValues.get(groupId));
+          break;
+        case TEXT:
+        case BLOB:
+        case STRING:
+          columnBuilder.writeBinary(binaryValues.get(groupId));
+          break;
+        case BOOLEAN:
+          columnBuilder.writeBoolean(booleanValues.get(groupId));
+          break;
+        default:
+          throw new UnSupportedDataTypeException(
+              String.format("Unsupported data type: %s", seriesDataType));
+      }
+    }
+  }
+
+  @Override
+  public void prepareFinal() {}
+
+  private void addIntInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateIntValue(groupIds[i], valueColumn.getInt(i));
+      }
+    }
+  }
+
+  protected void updateIntValue(int groupId, int value) {
+    int min = intValues.get(groupId);
+    if (value <= min) {
+      inits.set(groupId, true);
+      intValues.set(groupId, value);
+    }
+  }
+
+  private void addLongInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateLongValue(groupIds[i], valueColumn.getLong(i));
+      }
+    }
+  }
+
+  protected void updateLongValue(int groupId, long value) {
+    long min = longValues.get(groupId);
+    if (value <= min) {
+      inits.set(groupId, true);
+      longValues.set(groupId, value);
+    }
+  }
+
+  private void addFloatInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateFloatValue(groupIds[i], valueColumn.getFloat(i));
+      }
+    }
+  }
+
+  protected void updateFloatValue(int groupId, float value) {
+    float min = floatValues.get(groupId);
+    if (value <= min) {
+      inits.set(groupId, true);
+      floatValues.set(groupId, value);
+    }
+  }
+
+  private void addDoubleInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateDoubleValue(groupIds[i], valueColumn.getDouble(i));
+      }
+    }
+  }
+
+  protected void updateDoubleValue(int groupId, double value) {
+    double min = doubleValues.get(groupId);
+    if (value <= min) {
+      inits.set(groupId, true);
+      doubleValues.set(groupId, value);
+    }
+  }
+
+  private void addBinaryInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateBinaryValue(groupIds[i], valueColumn.getBinary(i));
+      }
+    }
+  }
+
+  protected void updateBinaryValue(int groupId, Binary value) {
+    Binary min = binaryValues.get(groupId);
+    if (!inits.get(groupId) || value.compareTo(min) < 0) {
+      inits.set(groupId, true);
+      binaryValues.set(groupId, value);
+    }
+  }
+
+  private void addBooleanInput(int[] groupIds, Column valueColumn) {
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!valueColumn.isNull(i)) {
+        updateBooleanValue(groupIds[i], valueColumn.getBoolean(i));
+      }
+    }
+  }
+
+  protected void updateBooleanValue(int groupId, boolean value) {
+    if (!inits.get(groupId) || !value) {
+      inits.set(groupId, true);
+      booleanValues.set(groupId, value);
+    }
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedSumAccumulator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedSumAccumulator.java
new file mode 100644
index 00000000000..0ba6d859de2
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/GroupedSumAccumulator.java
@@ -0,0 +1,152 @@
+/*
+ * 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.db.queryengine.execution.operator.source.relational.aggregation.grouped;
+
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BooleanBigArray;
+import 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.DoubleBigArray;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.utils.RamUsageEstimator;
+import org.apache.tsfile.write.UnSupportedDataTypeException;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class GroupedSumAccumulator implements GroupedAccumulator {
+  private static final long INSTANCE_SIZE =
+      RamUsageEstimator.shallowSizeOfInstance(GroupedSumAccumulator.class);
+  private final TSDataType argumentDataType;
+  private final BooleanBigArray initResult = new BooleanBigArray();
+  private final DoubleBigArray sumValues = new DoubleBigArray();
+
+  public GroupedSumAccumulator(TSDataType argumentDataType) {
+    this.argumentDataType = argumentDataType;
+  }
+
+  @Override
+  public long getEstimatedSize() {
+    return INSTANCE_SIZE + initResult.sizeOf() + sumValues.sizeOf();
+  }
+
+  @Override
+  public void setGroupCount(long groupCount) {
+    sumValues.ensureCapacity(groupCount);
+  }
+
+  @Override
+  public void addInput(int[] groupIds, Column[] arguments) {
+    checkArgument(arguments.length == 1, "argument of Sum should be one 
column");
+    switch (argumentDataType) {
+      case INT32:
+        addIntInput(groupIds, arguments[0]);
+        return;
+      case INT64:
+        addLongInput(groupIds, arguments[0]);
+        return;
+      case FLOAT:
+        addFloatInput(groupIds, arguments[0]);
+        return;
+      case DOUBLE:
+        addDoubleInput(groupIds, arguments[0]);
+        return;
+      case TEXT:
+      case BLOB:
+      case STRING:
+      case BOOLEAN:
+      case DATE:
+      case TIMESTAMP:
+      default:
+        throw new UnSupportedDataTypeException(
+            String.format("Unsupported data type in aggregation AVG : %s", 
argumentDataType));
+    }
+  }
+
+  @Override
+  public void addIntermediate(int[] groupIds, Column argument) {
+
+    for (int i = 0; i < groupIds.length; i++) {
+      if (!argument.isNull(i)) {
+        initResult.set(groupIds[i], true);
+        sumValues.add(groupIds[i], argument.getDouble(i));
+      }
+    }
+  }
+
+  @Override
+  public void evaluateIntermediate(int groupId, ColumnBuilder columnBuilder) {
+    if (!initResult.get(groupId)) {
+      columnBuilder.appendNull();
+    } else {
+      columnBuilder.writeDouble(sumValues.get(groupId));
+    }
+  }
+
+  private void addIntInput(int[] groupIds, Column column) {
+    int count = column.getPositionCount();
+    for (int i = 0; i < count; i++) {
+      if (!column.isNull(i)) {
+        initResult.set(groupIds[i], true);
+        sumValues.add(groupIds[i], column.getInt(i));
+      }
+    }
+  }
+
+  private void addLongInput(int[] groupIds, Column column) {
+    int count = column.getPositionCount();
+    for (int i = 0; i < count; i++) {
+      if (!column.isNull(i)) {
+        initResult.set(groupIds[i], true);
+        sumValues.add(groupIds[i], column.getLong(i));
+      }
+    }
+  }
+
+  private void addFloatInput(int[] groupIds, Column column) {
+    int count = column.getPositionCount();
+    for (int i = 0; i < count; i++) {
+      if (!column.isNull(i)) {
+        initResult.set(groupIds[i], true);
+        sumValues.add(groupIds[i], column.getFloat(i));
+      }
+    }
+  }
+
+  private void addDoubleInput(int[] groupIds, Column column) {
+    int count = column.getPositionCount();
+    for (int i = 0; i < count; i++) {
+      if (!column.isNull(i)) {
+        initResult.set(groupIds[i], true);
+        sumValues.add(groupIds[i], column.getDouble(i));
+      }
+    }
+  }
+
+  @Override
+  public void evaluateFinal(int groupId, ColumnBuilder columnBuilder) {
+    if (!initResult.get(groupId)) {
+      columnBuilder.appendNull();
+    } else {
+      columnBuilder.writeDouble(sumValues.get(groupId));
+    }
+  }
+
+  @Override
+  public void prepareFinal() {}
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/array/BinaryBigArray.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/array/BinaryBigArray.java
new file mode 100644
index 00000000000..0489c8be40d
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/array/BinaryBigArray.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed 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.db.queryengine.execution.operator.source.relational.aggregation.grouped.array;
+
+import org.apache.tsfile.utils.Binary;
+
+import static org.apache.tsfile.utils.RamUsageEstimator.shallowSizeOfInstance;
+import static org.apache.tsfile.utils.RamUsageEstimator.sizeOfObject;
+
+public final class BinaryBigArray {
+  private static final long INSTANCE_SIZE = 
shallowSizeOfInstance(BinaryBigArray.class);
+  private final ObjectBigArray<Binary> array;
+  private long sizeOfBinarys;
+
+  public BinaryBigArray() {
+    array = new ObjectBigArray<>();
+  }
+
+  public BinaryBigArray(Binary slice) {
+    array = new ObjectBigArray<>(slice);
+  }
+
+  /** Returns the size of this big array in bytes. */
+  public long sizeOf() {
+    return INSTANCE_SIZE + array.sizeOf() + sizeOfBinarys;
+  }
+
+  /**
+   * Returns the element of this big array at specified index.
+   *
+   * @param index a position in this big array.
+   * @return the element of this big array at the specified position.
+   */
+  public Binary get(long index) {
+    return array.get(index);
+  }
+
+  /**
+   * Sets the element of this big array at specified index.
+   *
+   * @param index a position in this big array.
+   */
+  public void set(long index, Binary value) {
+    updateRetainedSize(index, value);
+    array.set(index, value);
+  }
+
+  /**
+   * Ensures this big array is at least the specified length. If the array is 
smaller, segments are
+   * added until the array is larger then the specified length.
+   */
+  public void ensureCapacity(long length) {
+    array.ensureCapacity(length);
+  }
+
+  private void updateRetainedSize(long index, Binary value) {
+    Binary currentValue = array.get(index);
+    if (currentValue != null) {
+      sizeOfBinarys -= sizeOfObject(currentValue);
+    }
+    if (value != null) {
+      sizeOfBinarys += sizeOfObject(value);
+    }
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/array/FloatBigArray.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/array/FloatBigArray.java
new file mode 100644
index 00000000000..03869577b26
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/grouped/array/FloatBigArray.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed 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.db.queryengine.execution.operator.source.relational.aggregation.grouped.array;
+
+import java.util.Arrays;
+
+import static 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BigArrays.INITIAL_SEGMENTS;
+import static 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BigArrays.SEGMENT_SIZE;
+import static 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BigArrays.offset;
+import static 
org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation.grouped.array.BigArrays.segment;
+import static org.apache.tsfile.utils.RamUsageEstimator.shallowSizeOf;
+import static org.apache.tsfile.utils.RamUsageEstimator.shallowSizeOfInstance;
+import static org.apache.tsfile.utils.RamUsageEstimator.sizeOfFloatArray;
+
+// Note: this code was forked from fastutil (http://fastutil.di.unimi.it/)
+// Copyright (C) 2010-2013 Sebastiano Vigna
+public final class FloatBigArray {
+  private static final long INSTANCE_SIZE = 
shallowSizeOfInstance(FloatBigArray.class);
+  private static final long SIZE_OF_SEGMENT = sizeOfFloatArray(SEGMENT_SIZE);
+
+  private final float initialValue;
+
+  private float[][] array;
+  private long capacity;
+  private int segments;
+
+  /** Creates a new big array containing one initial segment */
+  public FloatBigArray() {
+    this(0.0F);
+  }
+
+  /**
+   * Creates a new big array containing one initial segment filled with the 
specified default value
+   */
+  public FloatBigArray(float initialValue) {
+    this.initialValue = initialValue;
+    array = new float[INITIAL_SEGMENTS][];
+    allocateNewSegment();
+  }
+
+  /** Returns the size of this big array in bytes. */
+  public long sizeOf() {
+    return INSTANCE_SIZE + shallowSizeOf(array) + (segments * SIZE_OF_SEGMENT);
+  }
+
+  /**
+   * Returns the element of this big array at specified index.
+   *
+   * @param index a position in this big array.
+   * @return the element of this big array at the specified position.
+   */
+  public float get(long index) {
+    return array[segment(index)][offset(index)];
+  }
+
+  /**
+   * Sets the element of this big array at specified index.
+   *
+   * @param index a position in this big array.
+   */
+  public void set(long index, float value) {
+    array[segment(index)][offset(index)] = value;
+  }
+
+  /**
+   * Adds the specified value to the specified element of this big array.
+   *
+   * @param index a position in this big array.
+   * @param value the value
+   */
+  public void add(long index, float value) {
+    array[segment(index)][offset(index)] += value;
+  }
+
+  /**
+   * Ensures this big array is at least the specified length. If the array is 
smaller, segments are
+   * added until the array is larger then the specified length.
+   */
+  public void ensureCapacity(long length) {
+    if (capacity > length) {
+      return;
+    }
+
+    grow(length);
+  }
+
+  /** Fills the entire big array with the specified value. */
+  public void fill(float value) {
+    for (float[] segment : array) {
+      if (segment == null) {
+        return;
+      }
+      Arrays.fill(segment, value);
+    }
+  }
+
+  /**
+   * Copies this array, beginning at the specified sourceIndex, to the 
specified destinationIndex of
+   * the destination array. A subsequence of this array's components are 
copied to the destination
+   * array referenced by {@code destination}. The number of components copied 
is equal to the {@code
+   * length} argument. The components at positions {@code sourceIndex} through 
{@code
+   * sourceIndex+length-1} in this array are copied into positions {@code 
destinationIndex} through
+   * {@code destinationIndex+length-1}, respectively, of the destination array.
+   */
+  public void copyTo(
+      long sourceIndex, FloatBigArray destination, long destinationIndex, long 
length) {
+    while (length > 0) {
+      int startSegment = segment(sourceIndex);
+      int startOffset = offset(sourceIndex);
+      int destinationStartSegment = segment(destinationIndex);
+      int destinationStartOffset = offset(destinationIndex);
+
+      int copyLength = Math.min(SEGMENT_SIZE - startOffset, SEGMENT_SIZE - 
destinationStartOffset);
+      copyLength =
+          Math.min(copyLength, length > Integer.MAX_VALUE ? Integer.MAX_VALUE 
: (int) length);
+
+      System.arraycopy(
+          array[startSegment],
+          startOffset,
+          destination.array[destinationStartSegment],
+          destinationStartOffset,
+          copyLength);
+
+      sourceIndex += copyLength;
+      destinationIndex += copyLength;
+      length -= copyLength;
+    }
+  }
+
+  private void grow(long length) {
+    // how many segments are required to get to the length?
+    int requiredSegments = segment(length) + 1;
+
+    // grow base array if necessary
+    if (array.length < requiredSegments) {
+      array = Arrays.copyOf(array, requiredSegments);
+    }
+
+    // add new segments
+    while (segments < requiredSegments) {
+      allocateNewSegment();
+    }
+  }
+
+  private void allocateNewSegment() {
+    float[] newSegment = new float[SEGMENT_SIZE];
+    if (initialValue != 0.0) {
+      Arrays.fill(newSegment, initialValue);
+    }
+    array[segments] = newSegment;
+    capacity += SEGMENT_SIZE;
+    segments++;
+  }
+}

Reply via email to