This is an automated email from the ASF dual-hosted git repository. jackietien pushed a commit to branch force_ci/object_type in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 0fc8e176e72f2341f82cf69750dc22b15d5cee15 Author: Jackie Tien <[email protected]> AuthorDate: Tue Nov 4 16:40:50 2025 +0800 Fix wrong push limit down to AggTableScanNode (#16696) (cherry picked from commit 8420beaaf5470b695c5d2afcb7491d226a7a8202) --- .../relational/it/query/recent/IoTDBTableAggregationIT.java | 13 +++++++++++++ .../planner/distribute/TableDistributedPlanGenerator.java | 2 +- .../planner/iterative/rule/PushDownOffsetIntoTableScan.java | 4 +++- .../relational/planner/node/AggregationTableScanNode.java | 10 ++++++++++ .../planner/optimizations/PushLimitOffsetIntoTableScan.java | 2 +- 5 files changed, 28 insertions(+), 3 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 0143bdb6e3b..88367283eb7 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 @@ -5491,4 +5491,17 @@ public class IoTDBTableAggregationIT { retArray, DATABASE_NAME); } + + @Test + public void orderByLimitTest() { + String[] expectedHeader = + new String[] {"province", "city", "region", "device_id", "_col4", "_col5"}; + String[] retArray = new String[] {"beijing,beijing,chaoyang,d09,2024-09-24T06:00:00.000Z,2,"}; + + tableResultSetEqualTest( + "select province, city, region, device_id, date_bin(1h, time), count(s1) from table1 where s1 >= 40 group by 1,2,3,4,5 order by province, city, region, device_id, date_bin(1h, time) limit 1", + expectedHeader, + retArray, + DATABASE_NAME); + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java index 850ef0a81e3..069d1df7469 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/distribute/TableDistributedPlanGenerator.java @@ -423,7 +423,7 @@ public class TableDistributedPlanGenerator private boolean canTopKEliminated(OrderingScheme orderingScheme, long k, PlanNode child) { // if DeviceTableScanNode has limit <= K and with same order, we can directly return // DeviceTableScanNode - if (child instanceof DeviceTableScanNode) { + if (child instanceof DeviceTableScanNode && !(child instanceof AggregationTableScanNode)) { DeviceTableScanNode tableScanNode = (DeviceTableScanNode) child; if (canSortEliminated(orderingScheme, nodeOrderingMap.get(child.getPlanNodeId()))) { if (tableScanNode.getPushDownLimit() <= 0) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/PushDownOffsetIntoTableScan.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/PushDownOffsetIntoTableScan.java index d683dbe3fdb..77143f90374 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/PushDownOffsetIntoTableScan.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/iterative/rule/PushDownOffsetIntoTableScan.java @@ -20,6 +20,7 @@ package org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.rule; import org.apache.iotdb.db.queryengine.plan.relational.planner.iterative.Rule; +import org.apache.iotdb.db.queryengine.plan.relational.planner.node.AggregationTableScanNode; import org.apache.iotdb.db.queryengine.plan.relational.planner.node.DeviceTableScanNode; import org.apache.iotdb.db.queryengine.plan.relational.planner.node.OffsetNode; import org.apache.iotdb.db.queryengine.plan.relational.planner.node.TableScanNode; @@ -53,7 +54,8 @@ public class PushDownOffsetIntoTableScan implements Rule<OffsetNode> { @Override public Result apply(OffsetNode parent, Captures captures, Context context) { TableScanNode tableScanNode = captures.get(CHILD); - if (tableScanNode instanceof DeviceTableScanNode + if ((tableScanNode instanceof DeviceTableScanNode + && !(tableScanNode instanceof AggregationTableScanNode)) && !((DeviceTableScanNode) tableScanNode).isPushLimitToEachDevice()) { tableScanNode.setPushDownOffset(parent.getCount()); // consider case that there is no limit diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/AggregationTableScanNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/AggregationTableScanNode.java index b6840d7200a..56d39f2f77d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/AggregationTableScanNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/AggregationTableScanNode.java @@ -623,4 +623,14 @@ public class AggregationTableScanNode extends DeviceTableScanNode { public Map<DeviceEntry, Integer> getDeviceCountMap() { return deviceCountMap; } + + @Override + public void setPushDownLimit(long pushDownLimit) { + throw new IllegalStateException("Should never push down limit to AggregationTableScanNode."); + } + + @Override + public void setPushDownOffset(long pushDownOffset) { + throw new IllegalStateException("Should never push down offset to AggregationTableScanNode."); + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushLimitOffsetIntoTableScan.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushLimitOffsetIntoTableScan.java index 2993c8f3696..2bd9b778aec 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushLimitOffsetIntoTableScan.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/PushLimitOffsetIntoTableScan.java @@ -50,7 +50,7 @@ import java.util.Set; import static org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.PushPredicateIntoTableScan.containsDiffFunction; /** - * <b>Optimization phase:</b> Distributed plan planning. + * <b>Optimization phase:</b> Logical plan planning. * * <p>The LIMIT OFFSET condition can be pushed down to the DeviceTableScanNode, when the following * conditions are met:
