This is an automated email from the ASF dual-hosted git repository.
xingtanzjr pushed a commit to branch yanshi
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/yanshi by this push:
new 80e87ff complete PlanNode Visulaizer
80e87ff is described below
commit 80e87ff2b6ccb313719aaa40492ee8557dd622ee
Author: Jinrui.Zhang <[email protected]>
AuthorDate: Wed Mar 30 11:48:43 2022 +0800
complete PlanNode Visulaizer
---
.../db/mpp/sql/planner/DistributionPlanner.java | 6 -
.../db/mpp/sql/planner/plan/node/PlanNode.java | 2 +-
.../sql/planner/plan/node/PlanNodeVisualizer.java | 122 ++++++++++-----------
.../planner/plan/node/source/SeriesScanNode.java | 4 +-
.../iotdb/db/mpp/operator/LimitOperatorTest.java | 21 ++--
.../db/mpp/sql/plan/DistributionPlannerTest.java | 28 ++++-
.../iotdb/db/mpp/sql/plan/QueryPlannerTest.java | 70 ------------
7 files changed, 93 insertions(+), 160 deletions(-)
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/DistributionPlanner.java
b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/DistributionPlanner.java
index af165ec..ee20717 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/DistributionPlanner.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/DistributionPlanner.java
@@ -65,13 +65,7 @@ public class DistributionPlanner {
public DistributedQueryPlan planFragments() {
PlanNode rootAfterRewrite = rewriteSource();
- System.out.println("\n===== Step 2: Partition SourceNode =====");
- System.out.println(PlanNodeUtil.nodeToString(rootAfterRewrite));
- PlanNodeVisualizer.printAsBox(rootAfterRewrite);
PlanNode rootWithExchange = addExchangeNode(rootAfterRewrite);
- System.out.println("\n===== Step 3: Add ExchangeNode =====");
- System.out.println(PlanNodeUtil.nodeToString(rootWithExchange));
- PlanNodeVisualizer.printAsBox(rootWithExchange);
SubPlan subPlan = splitFragment(rootWithExchange);
List<FragmentInstance> fragmentInstances = planFragmentInstances(subPlan);
return new DistributedQueryPlan(
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/PlanNode.java
b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/PlanNode.java
index 1f8555e..aa3b460 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/PlanNode.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/PlanNode.java
@@ -84,6 +84,6 @@ public abstract class PlanNode {
public abstract void serialize(ByteBuffer byteBuffer);
public List<String> getBoxString() {
- return ImmutableList.of("PlanNode");
+ return ImmutableList.of(String.format("PlanNode-%s", getId()));
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/PlanNodeVisualizer.java
b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/PlanNodeVisualizer.java
index cc2e137..35e47f6 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/PlanNodeVisualizer.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/PlanNodeVisualizer.java
@@ -34,7 +34,10 @@ public class PlanNodeVisualizer {
private static final String RIGHT_TOP = "┐";
private static final String SHANG = "┴";
private static final String XIA = "┬";
+ private static final String CROSS = "┼";
+ private static final int BOX_MARGIN = 1;
+ private static final int CONNECTION_LINE_HEIGHT = 2;
private static class Box {
private PlanNode node;
@@ -66,7 +69,15 @@ public class PlanNodeVisualizer {
if (idx < lines.size()) {
return lines.get(idx);
}
- return printIndent(lineWidth);
+ return genEmptyLine(lineWidth);
+ }
+
+ private String genEmptyLine(int lineWidth) {
+ StringBuilder line = new StringBuilder();
+ for (int i = 0; i < lineWidth; i++) {
+ line.append(INDENT);
+ }
+ return line.toString();
}
public int getChildrenLineCount() {
@@ -86,15 +97,15 @@ public class PlanNodeVisualizer {
}
}
- public static List<String> getBoxLines(PlanNode root) {
+ public static List<String> toBoxLines(PlanNode root) {
Box box = buildBoxTree(root);
- calculateBoxMaxWidth(box);
+ calculateBoxParams(box);
buildBoxLines(box);
return box.lines;
}
public static void printAsBox(PlanNode root) {
- for (String line : getBoxLines(root)) {
+ for (String line : toBoxLines(root)) {
System.out.println(line);
}
}
@@ -107,17 +118,17 @@ public class PlanNodeVisualizer {
return box;
}
- private static void calculateBoxMaxWidth(Box box) {
+ private static void calculateBoxParams(Box box) {
int childrenWidth = 0;
for (Box child : box.children) {
- calculateBoxMaxWidth(child);
+ calculateBoxParams(child);
childrenWidth += child.lineWidth;
}
- childrenWidth += box.children.size() > 1 ? box.children.size() - 1 : 0;
+ childrenWidth += box.childCount() > 1 ? (box.childCount() - 1) *
BOX_MARGIN : 0;
box.lineWidth = Math.max(box.boxWidth, childrenWidth);
box.startPosition = (box.lineWidth - box.boxWidth) / 2;
box.endPosition = box.startPosition + box.boxWidth - 1;
- box.midPosition = box.lineWidth / 2 - 1;
+ box.midPosition = box.lineWidth / 2;
}
private static void buildBoxLines(Box box) {
@@ -155,55 +166,44 @@ public class PlanNodeVisualizer {
// Print Connection Line
if (box.children.size() == 1) {
- for (int i = 0; i < 2; i++) {
- StringBuilder sb = new StringBuilder();
- for (int j = 0; j < box.lineWidth; j ++) {
- if (j == box.midPosition) {
- sb.append(SHU);
- } else {
- sb.append(INDENT);
- }
+ for (int i = 0; i < CONNECTION_LINE_HEIGHT; i++) {
+ StringBuilder line = new StringBuilder();
+ for (int j = 0; j < box.lineWidth; j++) {
+ line.append(j == box.midPosition ? SHU : INDENT);
}
- box.lines.add(sb.toString());
+ box.lines.add(line.toString());
}
} else {
Map<Integer, String> symbolMap = new HashMap<>();
+ Map<Integer, Boolean> childMidPositionMap = new HashMap<>();
symbolMap.put(box.midPosition, SHANG);
for (int i = 0; i < box.children.size(); i++) {
- symbolMap.put(getChildMidPosition(box, i), i == 0 ? LEFT_TOP : i ==
box.children.size() - 1 ? RIGHT_TOP : XIA);
+ int childMidPosition = getChildMidPosition(box, i);
+ childMidPositionMap.put(childMidPosition, true);
+ if (childMidPosition == box.midPosition) {
+ symbolMap.put(box.midPosition, CROSS);
+ continue;
+ }
+ symbolMap.put(
+ childMidPosition, i == 0 ? LEFT_TOP : i == box.children.size() - 1
? RIGHT_TOP : XIA);
}
StringBuilder line1 = new StringBuilder();
for (int i = 0; i < box.lineWidth; i++) {
- if (i < getChildMidPosition(box, 0)) {
- line1.append(INDENT);
- continue;
- }
- if (i > getChildMidPosition(box, box.childCount() - 1)) {
+ if (i < getChildMidPosition(box, 0) || i > getChildMidPosition(box,
box.childCount() - 1)) {
line1.append(INDENT);
continue;
}
line1.append(symbolMap.getOrDefault(i, HENG));
-
}
box.lines.add(line1.toString());
- StringBuilder line2 = new StringBuilder();
- for (int i = 0; i < box.lineWidth; i++) {
- if (i < getChildMidPosition(box, 0)) {
- line2.append(INDENT);
- continue;
- }
- if (i > getChildMidPosition(box, box.childCount() - 1)) {
- line2.append(INDENT);
- continue;
- }
- if (symbolMap.containsKey(i) && i != box.midPosition) {
- line2.append(SHU);
- } else {
- line2.append(INDENT);
+ for (int row = 1; row < CONNECTION_LINE_HEIGHT; row++) {
+ StringBuilder nextLine = new StringBuilder();
+ for (int i = 0; i < box.lineWidth; i++) {
+ nextLine.append(childMidPositionMap.containsKey(i) ? SHU : INDENT);
}
+ box.lines.add(nextLine.toString());
}
- box.lines.add(line2.toString());
}
for (Box child : box.children) {
@@ -215,7 +215,9 @@ public class PlanNodeVisualizer {
for (int j = 0; j < box.childCount(); j++) {
line.append(box.getChild(j).getLine(i));
if (j != box.childCount() - 1) {
- line.append(INDENT);
+ for (int m = 0; m < BOX_MARGIN; m++) {
+ line.append(INDENT);
+ }
}
}
box.lines.add(line.toString());
@@ -226,41 +228,27 @@ public class PlanNodeVisualizer {
int left = 0;
for (int i = 0; i < idx; i++) {
left += box.children.get(i).lineWidth;
- left += 1;
+ left += BOX_MARGIN;
}
left += box.children.get(idx).lineWidth / 2;
return left;
}
- private static String printIndent(int count) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < count; i++) {
- sb.append(INDENT);
- }
- return sb.toString();
- }
-
- private static String printBoxEdge(Box box, boolean top) {
- StringBuilder sb = new StringBuilder();
+ private static String printBoxEdge(Box box, boolean isTopEdge) {
+ StringBuilder line = new StringBuilder();
for (int i = 0; i < box.lineWidth; i++) {
if (i < box.startPosition) {
- sb.append(INDENT);
- continue;
- }
- if (i > box.endPosition) {
- sb.append(INDENT);
- continue;
- }
- if (i == box.startPosition) {
- sb.append(top ? LEFT_TOP : LEFT_BOTTOM);
- continue;
- }
- if (i == box.endPosition) {
- sb.append(top ? RIGHT_TOP : RIGHT_BOTTOM);
- continue;
+ line.append(INDENT);
+ } else if (i > box.endPosition) {
+ line.append(INDENT);
+ } else if (i == box.startPosition) {
+ line.append(isTopEdge ? LEFT_TOP : LEFT_BOTTOM);
+ } else if (i == box.endPosition) {
+ line.append(isTopEdge ? RIGHT_TOP : RIGHT_BOTTOM);
+ } else {
+ line.append(HENG);
}
- sb.append(HENG);
}
- return sb.toString();
+ return line.toString();
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/source/SeriesScanNode.java
b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/source/SeriesScanNode.java
index 9e6c04a..a1603db 100644
---
a/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/source/SeriesScanNode.java
+++
b/server/src/main/java/org/apache/iotdb/db/mpp/sql/planner/plan/node/source/SeriesScanNode.java
@@ -215,6 +215,8 @@ public class SeriesScanNode extends SourceNode {
}
private String getPartitionId() {
- return getDataRegionReplicaSet() == null ? "<Not Assigned>" :
getDataRegionReplicaSet().getId().toString();
+ return getDataRegionReplicaSet() == null
+ ? "<Not Assigned>"
+ : getDataRegionReplicaSet().getId().toString();
}
}
diff --git
a/server/src/test/java/org/apache/iotdb/db/mpp/operator/LimitOperatorTest.java
b/server/src/test/java/org/apache/iotdb/db/mpp/operator/LimitOperatorTest.java
index 77f689a..14cbeec 100644
---
a/server/src/test/java/org/apache/iotdb/db/mpp/operator/LimitOperatorTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/mpp/operator/LimitOperatorTest.java
@@ -131,27 +131,20 @@ public class LimitOperatorTest {
LimitOperator limitOperator =
new LimitOperator(
- fragmentInstanceContext.getOperatorContexts().get(3), 100,
timeJoinOperator);
+ fragmentInstanceContext.getOperatorContexts().get(3), 250,
timeJoinOperator);
int count = 0;
- System.out.println("Time sensor0 sensor1");
while (limitOperator.hasNext()) {
TsBlock tsBlock = limitOperator.next();
assertEquals(2, tsBlock.getValueColumnCount());
assertTrue(tsBlock.getColumn(0) instanceof IntColumn);
assertTrue(tsBlock.getColumn(1) instanceof IntColumn);
-// if (count < 12) {
-// assertEquals(20, tsBlock.getPositionCount());
-// } else {
-// assertEquals(10, tsBlock.getPositionCount());
-// }
+ if (count < 12) {
+ assertEquals(20, tsBlock.getPositionCount());
+ } else {
+ assertEquals(10, tsBlock.getPositionCount());
+ }
for (int i = 0; i < tsBlock.getPositionCount(); i++) {
long expectedTime = i + 20L * count;
- System.out.println(
- expectedTime
- + " \t "
- + tsBlock.getColumn(0).getInt(i)
- + " \t "
- + tsBlock.getColumn(1).getInt(i));
assertEquals(expectedTime, tsBlock.getTimeByIndex(i));
if (expectedTime < 200) {
assertEquals(20000 + expectedTime, tsBlock.getColumn(0).getInt(i));
@@ -168,7 +161,7 @@ public class LimitOperatorTest {
}
count++;
}
-// assertEquals(13, count);
+ assertEquals(13, count);
} catch (IOException | IllegalPathException e) {
e.printStackTrace();
fail();
diff --git
a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/DistributionPlannerTest.java
b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/DistributionPlannerTest.java
index 413bfc6..00139ad 100644
---
a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/DistributionPlannerTest.java
+++
b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/DistributionPlannerTest.java
@@ -38,6 +38,7 @@ import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNode;
import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeIdAllocator;
import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeUtil;
import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeVisualizer;
+import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.ExchangeNode;
import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.LimitNode;
import org.apache.iotdb.db.mpp.sql.planner.plan.node.process.TimeJoinNode;
import org.apache.iotdb.db.mpp.sql.planner.plan.node.source.SeriesScanNode;
@@ -50,6 +51,7 @@ import org.junit.Test;
import java.util.*;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
public class DistributionPlannerTest {
@@ -75,7 +77,6 @@ public class DistributionPlannerTest {
PlanNode newRoot = planner.rewriteSource();
System.out.println(PlanNodeUtil.nodeToString(newRoot));
- PlanNodeVisualizer.printAsBox(newRoot);
assertEquals(newRoot.getChildren().get(0).getChildren().size(), 3);
}
@@ -105,6 +106,30 @@ public class DistributionPlannerTest {
}
@Test
+ public void TestOneSeriesAddExchangeNode() throws IllegalPathException {
+ TimeJoinNode timeJoinNode =
+ new TimeJoinNode(
+ PlanNodeIdAllocator.generateId(), OrderBy.TIMESTAMP_ASC,
FilterNullPolicy.NO_FILTER);
+
+ timeJoinNode.addChild(
+ new SeriesScanNode(PlanNodeIdAllocator.generateId(), new
PartialPath("root.sg.d1.s1")));
+
+ LimitNode root = new LimitNode(PlanNodeIdAllocator.generateId(), 10,
timeJoinNode);
+
+ Analysis analysis = constructAnalysis();
+
+ DistributionPlanner planner =
+ new DistributionPlanner(analysis, new LogicalQueryPlan(new
MPPQueryContext(), root));
+ PlanNode rootAfterRewrite = planner.rewriteSource();
+ PlanNode rootWithExchange = planner.addExchangeNode(rootAfterRewrite);
+ PlanNode secondNode = rootWithExchange.getChildren().get(0);
+ assertTrue(
+ secondNode.getChildren().size() == 2
+ && (secondNode.getChildren().get(0) instanceof ExchangeNode
+ || secondNode.getChildren().get(1) instanceof ExchangeNode));
+ }
+
+ @Test
public void TestSplitFragment() throws IllegalPathException {
TimeJoinNode timeJoinNode =
new TimeJoinNode(
@@ -126,6 +151,7 @@ public class DistributionPlannerTest {
new DistributionPlanner(analysis, new LogicalQueryPlan(context, root));
PlanNode rootAfterRewrite = planner.rewriteSource();
PlanNode rootWithExchange = planner.addExchangeNode(rootAfterRewrite);
+ PlanNodeVisualizer.printAsBox(rootWithExchange);
SubPlan subPlan = planner.splitFragment(rootWithExchange);
assertEquals(subPlan.getChildren().size(), 2);
}
diff --git
a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/QueryPlannerTest.java
b/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/QueryPlannerTest.java
deleted file mode 100644
index dc74946..0000000
---
a/server/src/test/java/org/apache/iotdb/db/mpp/sql/plan/QueryPlannerTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.mpp.sql.plan;
-
-import org.apache.iotdb.db.mpp.common.MPPQueryContext;
-import org.apache.iotdb.db.mpp.common.QueryId;
-import org.apache.iotdb.db.mpp.common.SessionInfo;
-import org.apache.iotdb.db.mpp.execution.QueryExecution;
-import org.apache.iotdb.db.mpp.sql.analyze.QueryType;
-import org.apache.iotdb.db.mpp.sql.parser.StatementGenerator;
-import org.apache.iotdb.db.mpp.sql.planner.plan.DistributedQueryPlan;
-import org.apache.iotdb.db.mpp.sql.planner.plan.FragmentInstance;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeUtil;
-import org.apache.iotdb.db.mpp.sql.planner.plan.node.PlanNodeVisualizer;
-import org.apache.iotdb.db.mpp.sql.statement.Statement;
-
-import org.junit.Test;
-
-import java.time.ZoneId;
-
-public class QueryPlannerTest {
-
- @Test
- public void TestSqlToDistributedPlan() {
-
- String querySql = "SELECT d1.s1 FROM root.sg order by time desc LIMIT 10";
-
- Statement stmt = StatementGenerator.createStatement(querySql,
ZoneId.systemDefault());
-
- QueryExecution queryExecution =
- new QueryExecution(
- stmt,
- new MPPQueryContext(
- querySql, new QueryId("query1"), new SessionInfo(),
QueryType.READ));
- queryExecution.doLogicalPlan();
- System.out.printf("SQL: %s%n%n", querySql);
- System.out.println("\n===== Step 1: Logical Plan =====");
-
System.out.println(PlanNodeUtil.nodeToString(queryExecution.getLogicalPlan().getRootNode()));
-
PlanNodeVisualizer.printAsBox(queryExecution.getLogicalPlan().getRootNode());
-
- queryExecution.doDistributedPlan();
- DistributedQueryPlan distributedQueryPlan =
queryExecution.getDistributedPlan();
-
- System.out.println("\n===== Step 4: Split Fragment Instance =====");
- for (int i = 0 ; i < distributedQueryPlan.getInstances().size(); i ++) {
- System.out.println(String.format("--- Fragment Instance %d -----", i));
- FragmentInstance instance = distributedQueryPlan.getInstances().get(i);
- System.out.println(instance);
-// PlanNodeVisualizer.printAsBox(instance.getFragment().getRoot());
- System.out.println();
- }
- }
-}