You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ca...@apache.org on 2024/10/23 09:43:44 UTC

(iotdb) branch add_more_aggs updated (aad6f6057ec -> 491eb4ec1f8)

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

caogaofei pushed a change to branch add_more_aggs
in repository https://gitbox.apache.org/repos/asf/iotdb.git


    from aad6f6057ec fix it
     new 7d3285c639d add variance
     add dc96146d7c1 Fixed the cache invalidation logic when delete time series
     add 14a295ac825 Add Memory Control for HashAggregationOperator
     add d1c54d40dcd Fix compaction task comparator bug & Modify target file name of inner compaction task (#13848)
     add 7c98db11e05 Print file path while meeting unknown version tsfile
     add 516c32d527b Fix the issue that tasks with negative estimated memory are executed (#13856)
     add 7f5e5dc7bcd Fix timeout unit error in QueryExecution
     add c65a3b219cf Fix wal node memory leak when using simple consensus (#13864)
     add 57e450c5b18 Pipe: Reduce Calculations for PipeDataNodeRemainingEventAndTimeOperator when the events are too many (#13854)
     add aea9f3a4128 Fix ignored bitmap of attribute in writeTablet (#13858)
     add 574ba8ddd57 Active Load: Adjust the default execution thread to match the number of CPU cores (#13865)
     add bacde2f5b37 Support non-numeric type of max_by, min_by  GroupedAccumulators in TableModel
     add ce53f9c160e Pipe: Remove already deleted tsfile resource from historical extraction list to prevent FileNotFoundException (#13869)
     add 576b6d57e05 Fixed the measurement invalidation logic in TableDeviceLastCache
     add 9e48f9cf391 Optimize the serialize method of intermedia result of grouped aggregation
     add 38f7219a302 Clean walnode after drop database when using simple consensus (#13877)
     add 14346dc4098 Optimize the serialize method of intermedia result of aggregation
     add c93bdb77c03 Remove use of canUseStatistics when judge aggregation push-down level in TableModel
     add bbfc2f834ba Keep all null rows in table model flush (#13883)
     add 52b72edb689 Fix TimePartitionUtils Overflow (#13881)
     new 491eb4ec1f8 merge master

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../db/it/schema/IoTDBDeleteTimeSeriesIT.java      |  13 ++
 .../relational/it/db/it/IoTDBInsertTableIT.java    |  34 ++++
 .../db/it/IoTDBMultiIDsWithAttributesTableIT.java  |  42 +++++
 .../it/query/recent/IoTDBTableAggregationIT.java   |   1 +
 .../java/org/apache/iotdb/db/conf/IoTDBConfig.java |   2 +-
 .../org/apache/iotdb/db/conf/IoTDBDescriptor.java  |  16 +-
 .../connector/PipeConnectorSubtaskManager.java     |   6 -
 .../subtask/processor/PipeProcessorSubtask.java    |   6 +-
 .../db/pipe/event/common}/PipeInsertionEvent.java  |   3 +-
 .../event/common/heartbeat/PipeHeartbeatEvent.java |  15 +-
 .../db/pipe/event/common/row/PipeRowCollector.java |   2 +-
 .../tablet/PipeInsertNodeTabletInsertionEvent.java |  12 +-
 .../common/tablet/PipeRawTabletInsertionEvent.java |  11 +-
 .../common/tsfile/PipeTsFileInsertionEvent.java    |  12 +-
 .../tsfile/parser/TsFileInsertionEventParser.java  |   2 +-
 .../query/TsFileInsertionEventQueryParser.java     |   2 +-
 .../scan/TsFileInsertionEventScanParser.java       |   2 +-
 .../table/TsFileInsertionEventTableParser.java     |   2 +-
 .../db/pipe/event/realtime/PipeRealtimeEvent.java  |   2 +-
 .../dataregion/IoTDBDataRegionExtractor.java       |   2 -
 ...oricalDataRegionTsFileAndDeletionExtractor.java |  34 ++--
 .../matcher/CachedSchemaPatternMatcher.java        |   2 +-
 .../PipeDataNodeRemainingEventAndTimeMetrics.java  |  56 +++---
 .../PipeDataNodeRemainingEventAndTimeOperator.java |  95 ++++-------
 .../PipeConvertedInsertTabletStatement.java        |   2 +-
 .../relational/aggregation/AccumulatorFactory.java |  15 ++
 .../aggregation/TableVarianceAccumulator.java      | 187 +++++++++++++++++++++
 .../aggregation/grouped/GroupedAvgAccumulator.java |  20 +--
 .../grouped/GroupedFirstAccumulator.java           |  92 +++++-----
 .../grouped/GroupedFirstByAccumulator.java         | 115 +++++++------
 .../grouped/GroupedLastAccumulator.java            |  92 +++++-----
 .../grouped/GroupedLastByAccumulator.java          | 111 +++++++-----
 .../grouped/GroupedMaxByAccumulator.java           |   5 +
 .../grouped/GroupedMaxMinByBaseAccumulator.java    | 154 ++++++++++++-----
 .../grouped/GroupedMinByAccumulator.java           |   5 +
 .../grouped/HashAggregationOperator.java           |  18 +-
 .../aggregation/grouped/hash/FlatGroupByHash.java  |   4 +-
 .../queryengine/plan/execution/QueryExecution.java |   7 +-
 .../plan/relational/metadata/Metadata.java         |   6 -
 .../metadata/TableBuiltinAggregationFunction.java  |  33 ----
 .../relational/metadata/TableMetadataImpl.java     |   5 -
 .../fetcher/cache/TableDeviceLastCache.java        |  44 ++++-
 .../fetcher/cache/TableDeviceSchemaCache.java      |   7 +-
 .../cache/TreeDeviceSchemaCacheManager.java        |   9 +-
 .../PushAggregationIntoTableScan.java              |  12 +-
 .../plan/relational/sql/ast/InsertTablet.java      |  11 +-
 .../plan/statement/crud/InsertTabletStatement.java |  44 +++--
 .../iotdb/db/storageengine/StorageEngine.java      |  49 +++---
 .../execute/task/InnerSpaceCompactionTask.java     |   9 +-
 .../compaction/schedule/CompactionTaskQueue.java   |   3 +
 .../DefaultCompactionTaskComparatorImpl.java       |   8 +-
 .../dataregion/flush/MemTableFlushTask.java        |   2 +-
 .../memtable/AlignedWritableMemChunk.java          |   6 +-
 .../dataregion/memtable/IWritableMemChunk.java     |   5 +-
 .../dataregion/memtable/TsFileProcessor.java       | 125 +++++++-------
 .../dataregion/memtable/WritableMemChunk.java      |   2 +-
 .../dataregion/read/control/FileReaderManager.java |   4 +-
 .../tsfile/generator/TsFileNameGenerator.java      |   4 +-
 .../storageengine/dataregion/wal/WALManager.java   |  21 ++-
 .../dataregion/wal/allocation/ElasticStrategy.java |  27 ++-
 .../SubscriptionConnectorSubtaskManager.java       |   3 -
 .../plan/relational/analyzer/AggregationTest.java  |  19 ---
 .../plan/relational/analyzer/TSBSMetadata.java     |   6 -
 .../plan/relational/analyzer/TestMatadata.java     |   6 -
 .../plan/relational/sql/ast/InsertTabletTest.java  | 130 ++++++++++++++
 .../compaction/CompactionTaskComparatorTest.java   |  12 +-
 .../wal/allocation/ElasticStrategyTest.java        |  11 ++
 .../conf/iotdb-system.properties.template          |   4 +-
 .../iotdb/commons/utils/TimePartitionUtils.java    | 104 ++++++++++--
 .../commons/utils/TimePartitionUtilsTest.java      |  16 ++
 pom.xml                                            |   2 +-
 71 files changed, 1340 insertions(+), 610 deletions(-)
 rename iotdb-core/{node-commons/src/main/java/org/apache/iotdb/commons/pipe/event => datanode/src/main/java/org/apache/iotdb/db/pipe/event/common}/PipeInsertionEvent.java (97%)
 create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/TableVarianceAccumulator.java
 create mode 100644 iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/sql/ast/InsertTabletTest.java


(iotdb) 01/02: add variance

Posted by ca...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 7d3285c639d4f22e8531b830a32a8735a200f919
Author: Beyyes <cg...@foxmail.com>
AuthorDate: Wed Oct 23 17:40:02 2024 +0800

    add variance
---
 .../relational/aggregation/AccumulatorFactory.java |  15 ++
 .../aggregation/TableVarianceAccumulator.java      | 187 +++++++++++++++++++++
 2 files changed, 202 insertions(+)

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 cb59c7b2ac3..5003883eb45 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
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.queryengine.execution.operator.source.relational.aggregation;
 
 import org.apache.iotdb.common.rpc.thrift.TAggregationType;
+import org.apache.iotdb.db.queryengine.execution.aggregation.VarianceAccumulator;
 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;
@@ -181,6 +182,20 @@ public class AccumulatorFactory {
         return new ExtremeAccumulator(inputDataTypes.get(0));
       case MODE:
         return new TableModeAccumulator(inputDataTypes.get(0));
+      case STDDEV:
+      case STDDEV_SAMP:
+        return new TableVarianceAccumulator(
+            inputDataTypes.get(0), VarianceAccumulator.VarianceType.STDDEV_SAMP);
+      case STDDEV_POP:
+        return new TableVarianceAccumulator(
+            inputDataTypes.get(0), VarianceAccumulator.VarianceType.STDDEV_POP);
+      case VARIANCE:
+      case VAR_SAMP:
+        return new TableVarianceAccumulator(
+            inputDataTypes.get(0), VarianceAccumulator.VarianceType.VAR_SAMP);
+      case VAR_POP:
+        return new TableVarianceAccumulator(
+            inputDataTypes.get(0), VarianceAccumulator.VarianceType.VAR_POP);
       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/TableVarianceAccumulator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/TableVarianceAccumulator.java
new file mode 100644
index 00000000000..4cfb95c016f
--- /dev/null
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/aggregation/TableVarianceAccumulator.java
@@ -0,0 +1,187 @@
+/*
+ * 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;
+
+import org.apache.iotdb.db.queryengine.execution.aggregation.VarianceAccumulator;
+
+import org.apache.tsfile.block.column.Column;
+import org.apache.tsfile.block.column.ColumnBuilder;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.file.metadata.statistics.Statistics;
+import org.apache.tsfile.utils.Binary;
+import org.apache.tsfile.utils.BytesUtils;
+import org.apache.tsfile.write.UnSupportedDataTypeException;
+
+public class TableVarianceAccumulator implements TableAccumulator {
+
+  private final TSDataType seriesDataType;
+
+  private final VarianceAccumulator.VarianceType varianceType;
+
+  private long count;
+  private double mean;
+  private double m2;
+
+  public TableVarianceAccumulator(
+      TSDataType seriesDataType, VarianceAccumulator.VarianceType varianceType) {
+    this.seriesDataType = seriesDataType;
+    this.varianceType = varianceType;
+  }
+
+  @Override
+  public long getEstimatedSize() {
+    return 0;
+  }
+
+  @Override
+  public TableAccumulator copy() {
+    return null;
+  }
+
+  @Override
+  public void addInput(Column[] arguments) {
+    switch (seriesDataType) {
+      case INT32:
+        addIntInput(arguments[0]);
+        return;
+      case INT64:
+        // addLongInput(arguments[0]);
+        return;
+      case FLOAT:
+        // addFloatInput(arguments[0]);
+        return;
+      case DOUBLE:
+        // addDoubleInput(arguments[0]);
+        return;
+      case TEXT:
+      case BLOB:
+      case BOOLEAN:
+      case DATE:
+      case STRING:
+      case TIMESTAMP:
+      default:
+        throw new UnSupportedDataTypeException(
+            String.format("Unsupported data type in aggregation variance : %s", seriesDataType));
+    }
+  }
+
+  @Override
+  public void addIntermediate(Column argument) {
+    for (int i = 0; i < argument.getPositionCount(); i++) {
+      if (argument.isNull(i)) {
+        continue;
+      }
+
+      byte[] bytes = argument.getBinary(i).getValues();
+      long intermediateCount = BytesUtils.bytesToLong(bytes, Long.BYTES);
+      double intermediateMean = BytesUtils.bytesToDouble(bytes, Long.BYTES);
+      double intermediateM2 = BytesUtils.bytesToDouble(bytes, (Long.BYTES + Double.BYTES));
+
+      long newCount = count + intermediateCount;
+      double newMean = ((intermediateCount * intermediateMean) + (count * mean)) / newCount;
+      double delta = intermediateMean - mean;
+
+      m2 = m2 + intermediateM2 + delta * delta * intermediateCount * count / newCount;
+      count = newCount;
+      mean = newMean;
+    }
+  }
+
+  @Override
+  public void evaluateIntermediate(ColumnBuilder columnBuilder) {
+    if (count == 0) {
+      columnBuilder.appendNull();
+    } else {
+      byte[] bytes = new byte[24];
+      BytesUtils.longToBytes(count, bytes, 0);
+      BytesUtils.doubleToBytes(mean, bytes, Long.BYTES);
+      BytesUtils.doubleToBytes(m2, bytes, Long.BYTES + Double.BYTES);
+      columnBuilder.writeBinary(new Binary(bytes));
+    }
+  }
+
+  @Override
+  public void evaluateFinal(ColumnBuilder columnBuilder) {
+    switch (varianceType) {
+      case STDDEV_POP:
+        if (count == 0) {
+          columnBuilder.appendNull();
+        } else {
+          columnBuilder.writeDouble(Math.sqrt(m2 / count));
+        }
+        break;
+      case STDDEV_SAMP:
+        if (count < 2) {
+          columnBuilder.appendNull();
+        } else {
+          columnBuilder.writeDouble(Math.sqrt(m2 / (count - 1)));
+        }
+        break;
+      case VAR_POP:
+        if (count == 0) {
+          columnBuilder.appendNull();
+        } else {
+          columnBuilder.writeDouble(m2 / count);
+        }
+        break;
+      case VAR_SAMP:
+        if (count < 2) {
+          columnBuilder.appendNull();
+        } else {
+          columnBuilder.writeDouble(m2 / (count - 1));
+        }
+        break;
+      default:
+        throw new EnumConstantNotPresentException(
+            VarianceAccumulator.VarianceType.class, varianceType.name());
+    }
+  }
+
+  @Override
+  public boolean hasFinalResult() {
+    return false;
+  }
+
+  @Override
+  public void addStatistics(Statistics[] statistics) {
+    throw new UnsupportedOperationException(getClass().getName());
+  }
+
+  @Override
+  public void reset() {
+    count = 0;
+    mean = 0.0;
+    m2 = 0.0;
+  }
+
+  private void addIntInput(Column column) {
+    for (int i = 0; i < column.getPositionCount(); i++) {
+      if (column.isNull(i)) {
+        continue;
+      }
+
+      int value = column.getInt(i);
+      count++;
+      double delta = value - mean;
+      mean += delta / count;
+      m2 += delta * (value - mean);
+    }
+  }
+}


(iotdb) 02/02: merge master

Posted by ca...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 491eb4ec1f8a0aee8a01d6a13dbd94ec56476bf9
Merge: 7d3285c639d 52b72edb689
Author: Beyyes <cg...@foxmail.com>
AuthorDate: Wed Oct 23 17:43:30 2024 +0800

    merge master

 .../db/it/schema/IoTDBDeleteTimeSeriesIT.java      |  13 ++
 .../relational/it/db/it/IoTDBInsertTableIT.java    |  34 +++++
 .../db/it/IoTDBMultiIDsWithAttributesTableIT.java  |  42 ++++++
 .../it/query/recent/IoTDBTableAggregationIT.java   |   1 +
 .../java/org/apache/iotdb/db/conf/IoTDBConfig.java |   2 +-
 .../org/apache/iotdb/db/conf/IoTDBDescriptor.java  |  16 +--
 .../connector/PipeConnectorSubtaskManager.java     |   6 -
 .../subtask/processor/PipeProcessorSubtask.java    |   6 +-
 .../db/pipe/event/common}/PipeInsertionEvent.java  |   3 +-
 .../event/common/heartbeat/PipeHeartbeatEvent.java |  15 +-
 .../db/pipe/event/common/row/PipeRowCollector.java |   2 +-
 .../tablet/PipeInsertNodeTabletInsertionEvent.java |  12 +-
 .../common/tablet/PipeRawTabletInsertionEvent.java |  11 +-
 .../common/tsfile/PipeTsFileInsertionEvent.java    |  12 +-
 .../tsfile/parser/TsFileInsertionEventParser.java  |   2 +-
 .../query/TsFileInsertionEventQueryParser.java     |   2 +-
 .../scan/TsFileInsertionEventScanParser.java       |   2 +-
 .../table/TsFileInsertionEventTableParser.java     |   2 +-
 .../db/pipe/event/realtime/PipeRealtimeEvent.java  |   2 +-
 .../dataregion/IoTDBDataRegionExtractor.java       |   2 -
 ...oricalDataRegionTsFileAndDeletionExtractor.java |  34 +++--
 .../matcher/CachedSchemaPatternMatcher.java        |   2 +-
 .../PipeDataNodeRemainingEventAndTimeMetrics.java  |  56 ++++----
 .../PipeDataNodeRemainingEventAndTimeOperator.java |  95 +++++--------
 .../PipeConvertedInsertTabletStatement.java        |   2 +-
 .../aggregation/grouped/GroupedAvgAccumulator.java |  20 +--
 .../grouped/GroupedFirstAccumulator.java           |  92 ++++++------
 .../grouped/GroupedFirstByAccumulator.java         | 115 ++++++++-------
 .../grouped/GroupedLastAccumulator.java            |  92 ++++++------
 .../grouped/GroupedLastByAccumulator.java          | 111 +++++++++------
 .../grouped/GroupedMaxByAccumulator.java           |   5 +
 .../grouped/GroupedMaxMinByBaseAccumulator.java    | 154 ++++++++++++++++-----
 .../grouped/GroupedMinByAccumulator.java           |   5 +
 .../grouped/HashAggregationOperator.java           |  18 ++-
 .../aggregation/grouped/hash/FlatGroupByHash.java  |   4 +-
 .../queryengine/plan/execution/QueryExecution.java |   7 +-
 .../plan/relational/metadata/Metadata.java         |   6 -
 .../metadata/TableBuiltinAggregationFunction.java  |  33 -----
 .../relational/metadata/TableMetadataImpl.java     |   5 -
 .../fetcher/cache/TableDeviceLastCache.java        |  44 ++++--
 .../fetcher/cache/TableDeviceSchemaCache.java      |   7 +-
 .../cache/TreeDeviceSchemaCacheManager.java        |   9 +-
 .../PushAggregationIntoTableScan.java              |  12 +-
 .../plan/relational/sql/ast/InsertTablet.java      |  11 +-
 .../plan/statement/crud/InsertTabletStatement.java |  44 +++---
 .../iotdb/db/storageengine/StorageEngine.java      |  49 ++++---
 .../execute/task/InnerSpaceCompactionTask.java     |   9 +-
 .../compaction/schedule/CompactionTaskQueue.java   |   3 +
 .../DefaultCompactionTaskComparatorImpl.java       |   8 +-
 .../dataregion/flush/MemTableFlushTask.java        |   2 +-
 .../memtable/AlignedWritableMemChunk.java          |   6 +-
 .../dataregion/memtable/IWritableMemChunk.java     |   5 +-
 .../dataregion/memtable/TsFileProcessor.java       | 125 ++++++++---------
 .../dataregion/memtable/WritableMemChunk.java      |   2 +-
 .../dataregion/read/control/FileReaderManager.java |   4 +-
 .../tsfile/generator/TsFileNameGenerator.java      |   4 +-
 .../storageengine/dataregion/wal/WALManager.java   |  21 ++-
 .../dataregion/wal/allocation/ElasticStrategy.java |  27 +++-
 .../SubscriptionConnectorSubtaskManager.java       |   3 -
 .../plan/relational/analyzer/AggregationTest.java  |  19 ---
 .../plan/relational/analyzer/TSBSMetadata.java     |   6 -
 .../plan/relational/analyzer/TestMatadata.java     |   6 -
 .../plan/relational/sql/ast/InsertTabletTest.java  | 130 +++++++++++++++++
 .../compaction/CompactionTaskComparatorTest.java   |  12 +-
 .../wal/allocation/ElasticStrategyTest.java        |  11 ++
 .../conf/iotdb-system.properties.template          |   4 +-
 .../iotdb/commons/utils/TimePartitionUtils.java    | 104 ++++++++++++--
 .../commons/utils/TimePartitionUtilsTest.java      |  16 +++
 pom.xml                                            |   2 +-
 69 files changed, 1138 insertions(+), 610 deletions(-)

diff --cc integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBMultiIDsWithAttributesTableIT.java
index b0bb573c248,69f52276de6..dd2201577e1
--- a/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBMultiIDsWithAttributesTableIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/relational/it/db/it/IoTDBMultiIDsWithAttributesTableIT.java
@@@ -1153,29 -1176,27 +1176,48 @@@ public class IoTDBMultiIDsWithAttribute
      sql = "select extreme(num),extreme(bignum),extreme(floatnum) from table0";
      retArray = new String[] {"15,3147483648,4654.231,"};
      tableResultSetEqualTest(sql, expectedHeader, retArray, DATABASE_NAME);
+ 
+     // no push-down, test GroupedAccumulator
+     expectedHeader = buildHeaders(5);
+     retArray =
+         new String[] {
+           "1971-01-01T00:01:40.000Z,1971-01-01T00:00:00.000Z,1971-01-01T00:00:00.000Z,1971-01-01T00:01:40.000Z,3,",
+           "1971-04-26T17:46:40.000Z,1970-01-01T00:00:00.020Z,1970-01-01T00:00:00.020Z,1971-04-26T17:46:40.000Z,3,",
+           "1971-01-01T00:00:00.500Z,1970-01-01T00:00:00.040Z,1970-01-01T00:00:00.040Z,1971-04-26T17:46:40.020Z,3,",
+           "1971-01-01T00:00:01.000Z,1970-01-01T00:00:00.080Z,1971-04-26T18:01:40.000Z,1971-01-01T00:00:01.000Z,3,",
+           "1971-08-20T11:33:20.000Z,1971-01-01T00:00:10.000Z,1971-08-20T11:33:20.000Z,1970-01-01T00:00:00.100Z,3,",
+           "1971-01-01T00:01:40.000Z,1971-01-01T00:00:00.000Z,1971-01-01T00:00:00.000Z,1971-01-01T00:01:40.000Z,3,",
+           "1971-04-26T17:46:40.000Z,1970-01-01T00:00:00.020Z,1970-01-01T00:00:00.020Z,1971-04-26T17:46:40.000Z,3,",
+           "1971-01-01T00:00:00.500Z,1970-01-01T00:00:00.040Z,1970-01-01T00:00:00.040Z,1971-04-26T17:46:40.020Z,3,",
+           "1971-01-01T00:00:01.000Z,1970-01-01T00:00:00.080Z,1971-04-26T18:01:40.000Z,1971-01-01T00:00:01.000Z,3,",
+           "1971-08-20T11:33:20.000Z,1971-01-01T00:00:10.000Z,1971-08-20T11:33:20.000Z,1970-01-01T00:00:00.100Z,3,",
+         };
+     sql =
+         "select max_by(time,str),min_by(time,str),max_by(time,bool),min_by(time,bool),count(num+1) from table0 group by device,level order by device,level";
+     tableResultSetEqualTest(sql, expectedHeader, retArray, DATABASE_NAME);
    }
  
 +  @Test
 +  public void modeTest() {
 +    expectedHeader = buildHeaders(15);
 +    sql =
 +        "select mode(time),mode(device),mode(level),mode(attr1),mode(attr2),mode(num),mode(bignum),mode(floatnum),mode(date),mode(str),mode(bool),mode(date),mode(ts),mode(stringv),mode(doublenum) from table0 where device='d2' and level='l4' and time=80";
 +    retArray =
 +        new String[] {
 +          "1970-01-01T00:00:00.080Z,d2,l4,null,null,9,2147483646,43.12,null,apple,false,null,2024-09-20T06:15:35.000Z,test-string2,6666.7,",
 +        };
 +    tableResultSetEqualTest(sql, expectedHeader, retArray, DATABASE_NAME);
 +
 +    expectedHeader = buildHeaders(10);
 +    sql =
 +        "select mode(device),mode(level),mode(attr1),mode(attr2),mode(date),mode(bool),mode(date),mode(ts),mode(stringv),mode(doublenum) from table0 where device='d2' and level='l1'";
 +    retArray =
 +        new String[] {
 +          "d2,l1,d,c,null,false,null,2024-08-01T06:15:35.000Z,test-string3,null,",
 +        };
 +    tableResultSetEqualTest(sql, expectedHeader, retArray, DATABASE_NAME);
 +  }
 +
    // ==================================================================
    // ============================ Join Test ===========================
    // ==================================================================