diff --git a/fe/fe-core/src/main/java/org/apache/doris/common/profile/PlanTreeBuilder.java b/fe/fe-core/src/main/java/org/apache/doris/common/profile/PlanTreeBuilder.java index 3cbf37cdca..2a772ffc3c 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/common/profile/PlanTreeBuilder.java +++ b/fe/fe-core/src/main/java/org/apache/doris/common/profile/PlanTreeBuilder.java @@ -67,10 +67,16 @@ public class PlanTreeBuilder { } sb.append("\n[Fragment: ").append(fragment.getFragmentSequenceNum()).append("]"); sb.append("\n").append(sink.getExplainString("", TExplainLevel.BRIEF)); - sinkNode = new PlanTreeNode( - sink instanceof MultiCastDataSink ? ((MultiCastDataSink) sink).getDataStreamSinks().stream() - .map(s -> s.getExchNodeId()).collect(Collectors.toList()) - : ImmutableList.of(sink.getExchNodeId()), sb.toString()); + List exchangeIds; + if (sink instanceof MultiCastDataSink) { + exchangeIds = ((MultiCastDataSink) sink).getDataStreamSinks().stream() + .map(s -> s.getExchNodeId()).collect(Collectors.toList()); + } else if (sink.getExchNodeId() != null) { + exchangeIds = ImmutableList.of(sink.getExchNodeId()); + } else { + exchangeIds = ImmutableList.of(); + } + sinkNode = new PlanTreeNode(exchangeIds, sb.toString()); if (i == 0) { // sink of first fragment, set it as tree root treeRoot = sinkNode; diff --git a/regression-test/suites/nereids_p0/explain/explain_graph.groovy b/regression-test/suites/nereids_p0/explain/explain_graph.groovy new file mode 100644 index 0000000000..5ffb776de9 --- /dev/null +++ b/regression-test/suites/nereids_p0/explain/explain_graph.groovy @@ -0,0 +1,69 @@ +// 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. + +suite("explain_graph") { + // filter about invisible column "DORIS_DELETE_SIGN = 0" has no impaction on partition pruning + String db = context.config.getDbNameByFile(context.file) + sql "use ${db}" + sql "SET enable_nereids_planner=true" + sql "SET enable_fallback_to_original_planner=false" + sql "set partition_pruning_expand_threshold=10;" + sql "set ignore_shape_nodes='PhysicalDistribute,PhysicalProject'" + sql "drop table if exists T1;" + sql """ + CREATE TABLE T1 ( + a INT NULL, + b INT NULL, + c INT NULL + ) ENGINE=OLAP + UNIQUE KEY(`a`) + COMMENT 'OLAP' + DISTRIBUTED BY HASH(`a`) BUCKETS 10 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "min_load_replica_num" = "-1", + "is_being_synced" = "false", + "storage_format" = "V2", + "light_schema_change" = "true", + "disable_auto_compaction" = "false", + "enable_single_replica_compaction" = "false", + "group_commit_interval_ms" = "10000" + ); """ + + sql "drop table if exists T2;" + sql """ + CREATE TABLE T2 ( + a INT NULL, + b INT NULL, + c INT NULL + ) ENGINE=OLAP + UNIQUE KEY(`a`) + COMMENT 'OLAP' + DISTRIBUTED BY HASH(`a`) BUCKETS 10 + PROPERTIES ( + "replication_allocation" = "tag.location.default: 1", + "min_load_replica_num" = "-1", + "is_being_synced" = "false", + "storage_format" = "V2", + "light_schema_change" = "true", + "disable_auto_compaction" = "false", + "enable_single_replica_compaction" = "false", + "group_commit_interval_ms" = "10000" + ); """ + // make sure "explain graph" could work with "insert select" + sql "explain graph insert into T2 select * from T1" +} \ No newline at end of file