This is an automated email from the ASF dual-hosted git repository.
caogaofei pushed a commit to branch ty/TableModelGrammar
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/ty/TableModelGrammar by this
push:
new dbb378c3c02 Fix sort elimination, perfect explain output
dbb378c3c02 is described below
commit dbb378c3c02882ebf315e0bba74d1b0e805b6d0b
Author: Beyyes <[email protected]>
AuthorDate: Wed Jul 24 16:51:20 2024 +0800
Fix sort elimination, perfect explain output
---
.../TableModelStatementMemorySourceVisitor.java | 34 ++++++++++++++++++++--
.../plan/planner/plan/node/PlanGraphPrinter.java | 10 +++++++
.../planner/optimizations/SortElimination.java | 19 ++++++++++--
3 files changed, 57 insertions(+), 6 deletions(-)
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceVisitor.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceVisitor.java
index ec9c5d145f3..d92db81e1bd 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceVisitor.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/memory/TableModelStatementMemorySourceVisitor.java
@@ -22,13 +22,17 @@ package
org.apache.iotdb.db.queryengine.plan.execution.memory;
import org.apache.iotdb.commons.conf.IoTDBConstant;
import org.apache.iotdb.db.queryengine.common.header.ColumnHeader;
import org.apache.iotdb.db.queryengine.common.header.DatasetHeader;
-import org.apache.iotdb.db.queryengine.execution.warnings.WarningCollector;
import org.apache.iotdb.db.queryengine.plan.planner.LocalExecutionPlanner;
import org.apache.iotdb.db.queryengine.plan.planner.plan.LogicalQueryPlan;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanGraphPrinter;
import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode;
+import
org.apache.iotdb.db.queryengine.plan.relational.execution.querystats.PlanOptimizersStatsCollector;
+import org.apache.iotdb.db.queryengine.plan.relational.planner.SymbolAllocator;
import
org.apache.iotdb.db.queryengine.plan.relational.planner.distribute.AddExchangeNodes;
import
org.apache.iotdb.db.queryengine.plan.relational.planner.distribute.DistributedPlanGenerator;
+import
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.PlanOptimizer;
+import
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.PushLimitOffsetIntoTableScan;
+import
org.apache.iotdb.db.queryengine.plan.relational.planner.optimizations.SortElimination;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.AstVisitor;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Explain;
import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Node;
@@ -36,11 +40,13 @@ import
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Node;
import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.read.common.block.TsBlock;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
import static
org.apache.iotdb.db.queryengine.common.header.DatasetHeader.EMPTY_HEADER;
+import static
org.apache.iotdb.db.queryengine.execution.warnings.WarningCollector.NOOP;
import static
org.apache.iotdb.db.queryengine.plan.execution.memory.StatementMemorySourceVisitor.getStatementMemorySource;
public class TableModelStatementMemorySourceVisitor
@@ -68,7 +74,7 @@ public class TableModelStatementMemorySourceVisitor
context.getQueryContext(),
LocalExecutionPlanner.getInstance().metadata,
context.getQueryContext().getSession(),
- WarningCollector.NOOP)
+ NOOP)
.plan(context.getAnalysis());
if (context.getAnalysis().isEmptyDataSource()) {
return new StatementMemorySource(new TsBlock(0), header);
@@ -81,10 +87,32 @@ public class TableModelStatementMemorySourceVisitor
.genResult(logicalPlan.getRootNode(), planContext);
checkArgument(distributedPlanResult.size() == 1, "Root node must return
only one");
+ // Notice: when change the optimizers in TableDistributionPlanner, these
code also need to be
+ // adapted
+ List<PlanOptimizer> optimizers =
+ Arrays.asList(new PushLimitOffsetIntoTableScan(), new
SortElimination());
+ // distribute plan optimize rule
+ PlanNode distributedPlan = distributedPlanResult.get(0);
+ for (PlanOptimizer optimizer : optimizers) {
+ distributedPlan =
+ optimizer.optimize(
+ distributedPlan,
+ new PlanOptimizer.Context(
+ null,
+ context.getAnalysis(),
+ null,
+ context.getQueryContext(),
+ context.getQueryContext().getTypeProvider(),
+ new SymbolAllocator(),
+ context.getQueryContext().getQueryId(),
+ NOOP,
+
PlanOptimizersStatsCollector.createPlanOptimizersStatsCollector()));
+ }
+
// add exchange node for distributed plan
PlanNode outputNodeWithExchange =
new AddExchangeNodes(context.getQueryContext())
- .addExchangeNodes(distributedPlanResult.get(0), planContext);
+ .addExchangeNodes(distributedPlan, planContext);
List<String> lines =
outputNodeWithExchange.accept(
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanGraphPrinter.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanGraphPrinter.java
index c55996874f9..9a0ea93d608 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanGraphPrinter.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/node/PlanGraphPrinter.java
@@ -698,6 +698,16 @@ public class PlanGraphPrinter extends
PlanVisitor<List<String>, PlanGraphPrinter
return render(node, boxValue, context);
}
+ @Override
+ public List<String> visitCollect(
+ org.apache.iotdb.db.queryengine.plan.relational.planner.node.CollectNode
node,
+ GraphContext context) {
+ List<String> boxValue = new ArrayList<>();
+ boxValue.add(String.format("Collect-%s", node.getPlanNodeId().getId()));
+ boxValue.add(String.format("OutputSymbols: %s", node.getOutputSymbols()));
+ return render(node, boxValue, context);
+ }
+
private String printRegion(TRegionReplicaSet regionReplicaSet) {
return String.format(
"Partition: %s",
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/SortElimination.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/SortElimination.java
index 23bb78c8da4..6ab922361a7 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/SortElimination.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/optimizations/SortElimination.java
@@ -68,10 +68,11 @@ public class SortElimination implements PlanOptimizer {
@Override
public PlanNode visitSort(SortNode node, Context context) {
- PlanNode child = node.getChild().accept(this, context);
- TableScanNode tableScanNode = context.getTableScanNode();
+ Context newContext = new Context();
+ PlanNode child = node.getChild().accept(this, newContext);
OrderingScheme orderingScheme = node.getOrderingScheme();
- if (tableScanNode.getDeviceEntries().size() == 1
+ TableScanNode tableScanNode = newContext.getTableScanNode();
+ if (newContext.getTotalDeviceEntrySize() == 1
&&
TIMESTAMP_STR.equalsIgnoreCase(orderingScheme.getOrderBy().get(0).getName())) {
return child;
}
@@ -87,6 +88,7 @@ public class SortElimination implements PlanOptimizer {
@Override
public PlanNode visitTableScan(TableScanNode node, Context context) {
+ context.addDeviceEntrySize(node.getDeviceEntries().size());
context.setTableScanNode(node);
return node;
}
@@ -121,8 +123,19 @@ public class SortElimination implements PlanOptimizer {
}
private static class Context {
+ private int totalDeviceEntrySize = 0;
private TableScanNode tableScanNode;
+ Context() {}
+
+ public void addDeviceEntrySize(int deviceEntrySize) {
+ this.totalDeviceEntrySize += deviceEntrySize;
+ }
+
+ public int getTotalDeviceEntrySize() {
+ return totalDeviceEntrySize;
+ }
+
public TableScanNode getTableScanNode() {
return tableScanNode;
}