JackieTien97 commented on code in PR #18204: URL: https://github.com/apache/iotdb/pull/18204#discussion_r3584933099
########## iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/TopKRuntimeFilterOptimizer.java: ########## @@ -0,0 +1,98 @@ +/* + * 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.plan.relational.planner.optimizations; + +import org.apache.iotdb.commons.queryengine.plan.planner.plan.node.PlanNode; +import org.apache.iotdb.commons.queryengine.plan.relational.planner.node.TopKNode; +import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanVisitor; +import org.apache.iotdb.db.queryengine.plan.relational.planner.node.AggregationTableScanNode; +import org.apache.iotdb.db.queryengine.plan.relational.planner.node.DeviceTableScanNode; + +/** + * <b>Optimization phase:</b> Distributed plan planning (after exchange nodes are inserted). + * + * <p>Marks the {@code TopK + DeviceTableScan} structure for TopK runtime filter. + * + * <p>The topmost TopK establishes the <b>root TopK id</b>. In the single-region case ({@code Output + * -> TopK -> Scan}), the producer TopK uses its own plan node id as the root id. A per-region TopK + * that sits directly on top of {@link DeviceTableScanNode}(s) becomes the runtime filter producer, + * and both that TopK and its scan children are tagged with the <b>root</b> TopK id (not the region + * TopK's own id when a coordinator TopK exists above Exchange). Because {@code + * DataNodeQueryContext} is shared by all fragment instances of the same query on one DataNode, + * using the root id lets multiple regions on the same DataNode share a single filter. + */ +public class TopKRuntimeFilterOptimizer implements PlanOptimizer { + + @Override + public PlanNode optimize(PlanNode plan, Context context) { + if (!context.getAnalysis().isQuery()) { + return plan; + } + return plan.accept(new Rewriter(), null); + } + + /** Context carries the root TopK id string, or {@code null} until the first TopK is seen. */ + private static class Rewriter implements PlanVisitor<PlanNode, String> { + + @Override + public PlanNode visitPlan(PlanNode node, String rootTopKId) { + PlanNode newNode = node.clone(); + for (PlanNode child : node.getChildren()) { + newNode.addChild(child.accept(this, rootTopKId)); + } + return newNode; + } + + @Override + public PlanNode visitTopK(TopKNode node, String rootTopKId) { + TopKNode topKNode = (TopKNode) node.clone(); + + boolean orderByTimeOnly = TopKRuntimeFilterUtils.isOrderByTimeOnly(node.getOrderingScheme()); + String effectiveRootTopKId = resolveEffectiveRootTopKId(node, rootTopKId); Review Comment: what if outer TopK -> Union / Join -> inner TopK A -> Scan -> inner TopK B -> Scan ########## iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/source/relational/ExternalTsFileTableScanOperator.java: ########## @@ -97,6 +97,16 @@ public void initQueryDataSource(IQueryDataSource dataSource) { super.initQueryDataSource(currentDataSource); } + @Override + protected boolean shouldStopScanByRuntimeFilter() { + // Each device uses its own QueryDataSource; exhausting files for a non-last device must not + // stop scanning remaining devices in the same external TsFile task. + if (currentDeviceIndex < deviceCount - 1) { + return false; + } + return super.shouldStopScanByRuntimeFilter(); Review Comment: super class's queryDataSource belongs to first device, not the last device. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
