Skip to content
Permalink
Browse files

Render plan structure

Make the tree structure of the plan clearer. Sample output:

                                                   Query Plan
----------------------------------------------------------------------------------------------------------------
 Output[_col0]
 │   Layout: [count:bigint]
 │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
 │   _col0 := count
 └── Aggregate(FINAL)
     │   Layout: [count:bigint]
     │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
     │   count := "count"("count_9")
     └── LocalExchange[SINGLE] ()
         │   Layout: [count_9:bigint]
         │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
         └── RemoteExchange[GATHER]
             │   Layout: [count_9:bigint]
             │   Estimates: {rows: ? (?), cpu: ?, memory: ?, network: ?}
             └── Aggregate(PARTIAL)
                 │   Layout: [count_9:bigint]
                 │   count_9 := "count"(*)
                 └── InnerJoin[("orderkey" = "orderkey_0")]
                     │   Layout: []
                     │   Estimates: {rows: 60175 (0B), cpu: 2.32M, memory: 528.88kB, network: 528.88kB}
                     │   Distribution: PARTITIONED
                     ├── TableScan[tpch:orders:sf0.01]
                     │       Layout: [orderkey:bigint]
                     │       Estimates: {rows: 15000 (131.84kB), cpu: 131.84k, memory: 0B, network: 0B}
                     │       orderkey := tpch:orderkey
                     │       tpch:orderstatus
                     │           :: [[F], [O], [P]]
                     └── LocalExchange[HASH] ("orderkey_0")
                         │   Layout: [orderkey_0:bigint]
                         │   Estimates: {rows: 60175 (528.88kB), cpu: 1.55M, memory: 0B, network: 528.88kB}
                         └── RemoteExchange[REPARTITION]
                             │   Layout: [orderkey_0:bigint]
                             │   Estimates: {rows: 60175 (528.88kB), cpu: 1.03M, memory: 0B, network: 528.88kB}
                             └── TableScan[tpch:lineitem:sf0.01]
                                     Layout: [orderkey_0:bigint]
                                     Estimates: {rows: 60175 (528.88kB), cpu: 528.88k, memory: 0B, network: 0B}
                                     orderkey_0 := tpch:orderkey
  • Loading branch information...
martint committed Jun 2, 2019
1 parent 6651ea4 commit 23806bda30f03ec8ed56f5c4082e905aab016042
Showing with 63 additions and 12 deletions.
  1. +63 −12 presto-main/src/main/java/io/prestosql/sql/planner/planprinter/TextRenderer.java
@@ -21,6 +21,7 @@
import io.prestosql.sql.planner.Symbol;
import io.prestosql.sql.planner.planprinter.NodeRepresentation.TypedSymbol;

import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -54,13 +55,13 @@ public TextRenderer(boolean verbose, int level)
public String render(PlanRepresentation plan)
{
StringBuilder output = new StringBuilder();
return writeTextOutput(output, plan, level, plan.getRoot());
NodeRepresentation root = plan.getRoot();
return writeTextOutput(output, plan, Indent.newInstance(!root.getChildren().isEmpty()), root);
}

private String writeTextOutput(StringBuilder output, PlanRepresentation plan, int level, NodeRepresentation node)
private String writeTextOutput(StringBuilder output, PlanRepresentation plan, Indent indent, NodeRepresentation node)
{
output.append(indentString(level))
.append("- ")
output.append(indent.nodeIndent())
.append(node.getName())
.append(node.getIdentifier())
.append("\n");
@@ -69,20 +70,20 @@ private String writeTextOutput(StringBuilder output, PlanRepresentation plan, in
.map(s -> s.getSymbol() + ":" + s.getType())
.collect(joining(", "));

output.append(indentMultilineString("Layout: [" + columns + "]\n", level + 2));
output.append(indentMultilineString("Layout: [" + columns + "]\n", indent.detailIndent()));

String estimates = printEstimates(plan, node);
if (!estimates.isEmpty()) {
output.append(indentMultilineString(estimates, level + 2));
output.append(indentMultilineString(estimates, indent.detailIndent()));
}

String stats = printStats(plan, node);
if (!stats.isEmpty()) {
output.append(indentMultilineString(stats, level + 2));
output.append(indentMultilineString(stats, indent.detailIndent()));
}

if (!node.getDetails().isEmpty()) {
String details = indentMultilineString(node.getDetails(), level + 2);
String details = indentMultilineString(node.getDetails(), indent.detailIndent());
output.append(details);
if (!details.endsWith("\n")) {
output.append('\n');
@@ -95,8 +96,15 @@ private String writeTextOutput(StringBuilder output, PlanRepresentation plan, in
.map(Optional::get)
.collect(toList());

for (NodeRepresentation child : children) {
writeTextOutput(output, plan, level + 1, child);
for (Iterator<NodeRepresentation> iterator = children.iterator(); iterator.hasNext(); ) {
NodeRepresentation child = iterator.next();

boolean hasChildren = child.getChildren().stream()
.map(plan::getNode)
.filter(Optional::isPresent)
.count() > 0;

writeTextOutput(output, plan, indent.forChild(!iterator.hasNext(), hasChildren), child);
}

return output.toString();
@@ -294,8 +302,51 @@ static String indentString(int indent)
return Strings.repeat(" ", indent);
}

private static String indentMultilineString(String string, int level)
private static String indentMultilineString(String string, String indent)
{
return string.replaceAll("(?m)^", indent);
}

private static class Indent
{
return string.replaceAll("(?m)^", indentString(level));
private final String firstLine;
private final String nextLines;
private final boolean hasChildren;

public static Indent newInstance(boolean hasChildren)
{
return new Indent("", "", hasChildren);
}

private Indent(String firstLine, String nextLines, boolean hasChildren)
{
this.firstLine = firstLine;
this.nextLines = nextLines;
this.hasChildren = hasChildren;
}

public Indent forChild(boolean last, boolean hasChildren)
{
if (last) {
return new Indent(nextLines + "\u2514\u2500 ", nextLines + " ", hasChildren);
}

return new Indent(nextLines + "\u251c\u2500 ", nextLines + "\u2502 ", hasChildren);
}

public String nodeIndent()
{
return firstLine;
}

public String detailIndent()
{
if (hasChildren) {
return nextLines + "\u2502 ";
}
else {
return nextLines + " ";
}
}
}
}

0 comments on commit 23806bd

Please sign in to comment.
You can’t perform that action at this time.