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();
-    }
-  }
-}

Reply via email to