[Feature](Nereids) Add explain tree functionality. (#25446)
Add explain tree functionality which contains fragment ids for profile analysis. ``` mysql> explain tree select sum(l_orderkey) from lineitem, orders where l_orderkey = o_orderkey; +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Explain String(Nereids Planner) | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | [414]:[414: ResultSink]||[Fragment: 0]||VRESULT SINK|| MYSQL_PROTOCAL|| | | --[414]:[414: VAGGREGATE (merge finalize)]||[Fragment: 0]||cardinality=1|| | | ----[411]:[411: VEXCHANGE]||[Fragment: 0]||offset: 0|| | | ------[411]:[411: DataStreamSink]||[Fragment: 1]||STREAM DATA SINK|| EXCHANGE ID: 411|| UNPARTITIONED | | --------[408]:[408: VAGGREGATE (update serialize)]||[Fragment: 1]||cardinality=1|| | | ----------[402]:[402: VHASH JOIN]||[Fragment: 1]||join op: INNER JOIN(PARTITIONED)[]||cardinality=593,132,346|| | | ------------[392]:[392: VEXCHANGE]||[Fragment: 1]||offset: 0|| | | --------------[392]:[392: DataStreamSink]||[Fragment: 2]||STREAM DATA SINK|| EXCHANGE ID: 392|| HASH_PARTITIONED | | ----------------[386]:[386: VHIVE_SCAN_NODE]||[Fragment: 2]||table: lineitem||inputSplitNum=144, totalFileSize=16632158739, scanRanges=144||partition=1/1||cardinality=600037902, numNodes=1||pushdown agg=NONE|| | | ------------[399]:[399: VEXCHANGE]||[Fragment: 1]||offset: 0|| | | --------------[399]:[399: DataStreamSink]||[Fragment: 3]||STREAM DATA SINK|| EXCHANGE ID: 399|| HASH_PARTITIONED | | ----------------[393]:[393: VHIVE_SCAN_NODE]||[Fragment: 3]||table: orders||inputSplitNum=48, totalFileSize=3984213353, scanRanges=48||partition=1/1||cardinality=150000000, numNodes=1||pushdown agg=NONE|| | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 12 rows in set (0.04 sec) ```
This commit is contained in:
@ -23,6 +23,8 @@ import org.apache.doris.nereids.trees.plans.commands.ExplainCommand.ExplainLevel
|
||||
public class ExplainOptions {
|
||||
|
||||
private boolean isVerbose;
|
||||
|
||||
private boolean isTree;
|
||||
private boolean isGraph;
|
||||
|
||||
private ExplainCommand.ExplainLevel explainLevel;
|
||||
@ -31,8 +33,9 @@ public class ExplainOptions {
|
||||
this.explainLevel = explainLevel;
|
||||
}
|
||||
|
||||
public ExplainOptions(boolean isVerbose, boolean isGraph) {
|
||||
public ExplainOptions(boolean isVerbose, boolean isTree, boolean isGraph) {
|
||||
this.isVerbose = isVerbose;
|
||||
this.isTree = isTree;
|
||||
this.isGraph = isGraph;
|
||||
}
|
||||
|
||||
@ -40,6 +43,10 @@ public class ExplainOptions {
|
||||
return explainLevel == ExplainLevel.VERBOSE || isVerbose;
|
||||
}
|
||||
|
||||
public boolean isTree() {
|
||||
return explainLevel == ExplainLevel.TREE || isTree;
|
||||
}
|
||||
|
||||
public boolean isGraph() {
|
||||
return explainLevel == ExplainLevel.GRAPH || isGraph;
|
||||
}
|
||||
|
||||
@ -23,6 +23,8 @@ import hu.webarticum.treeprinter.TraditionalTreePrinter;
|
||||
|
||||
public class PlanTreePrinter {
|
||||
|
||||
private static final String DELIMITER = "||";
|
||||
|
||||
public static String printPlanExplanation(PlanTreeNode root) {
|
||||
SimpleTreeNode rootNode = buildNode(root);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@ -37,4 +39,21 @@ public class PlanTreePrinter {
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
public static String printPlanTree(PlanTreeNode root) {
|
||||
return buildTree(root, "");
|
||||
}
|
||||
|
||||
private static String buildTree(PlanTreeNode planNode, String prefix) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append(prefix).append(planNode.getIds()).append(":")
|
||||
.append(planNode.getExplainStr().replaceAll("\n", DELIMITER)).append("\n");
|
||||
String childPrefix = prefix + "--";
|
||||
planNode.getChildren().forEach(
|
||||
child -> {
|
||||
builder.append(buildTree(child, childPrefix));
|
||||
}
|
||||
);
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ public class ExplainCommand extends Command implements NoForward {
|
||||
NONE(false),
|
||||
NORMAL(false),
|
||||
VERBOSE(false),
|
||||
TREE(false),
|
||||
GRAPH(false),
|
||||
PARSED_PLAN(true),
|
||||
ANALYZED_PLAN(true),
|
||||
|
||||
@ -70,6 +70,17 @@ public abstract class Planner {
|
||||
}
|
||||
return PlanTreePrinter.printPlanExplanation(builder.getTreeRoot());
|
||||
}
|
||||
if (explainOptions.isTree()) {
|
||||
// print the plan tree
|
||||
PlanTreeBuilder builder = new PlanTreeBuilder(fragments);
|
||||
try {
|
||||
builder.build();
|
||||
} catch (UserException e) {
|
||||
LOG.warn("Failed to build explain plan tree", e);
|
||||
return e.getMessage();
|
||||
}
|
||||
return PlanTreePrinter.printPlanTree(builder.getTreeRoot());
|
||||
}
|
||||
|
||||
// print text plan
|
||||
org.apache.doris.thrift.TExplainLevel
|
||||
|
||||
Reference in New Issue
Block a user