(plan *pb.QueryPlan, idx int32)
| 81 | } |
| 82 | |
| 83 | func BuildQueryPlanTree(plan *pb.QueryPlan, idx int32) *Node { |
| 84 | if len(plan.PlanNodes) == 0 { |
| 85 | return &Node{} |
| 86 | } |
| 87 | |
| 88 | nodeMap := map[int32]*pb.PlanNode{} |
| 89 | for _, node := range plan.PlanNodes { |
| 90 | nodeMap[node.Index] = node |
| 91 | } |
| 92 | |
| 93 | root := &Node{ |
| 94 | PlanNode: plan.PlanNodes[idx], |
| 95 | Children: make([]*Link, 0), |
| 96 | } |
| 97 | if root.PlanNode.ChildLinks != nil { |
| 98 | for i, childLink := range root.PlanNode.ChildLinks { |
| 99 | idx := childLink.ChildIndex |
| 100 | child := BuildQueryPlanTree(plan, idx) |
| 101 | childType := childLink.Type |
| 102 | |
| 103 | // Fill missing Input type into the first child of [Distributed] (Cross|Outer) Apply |
| 104 | if childType == "" && strings.HasSuffix(root.PlanNode.DisplayName, "Apply") && i == 0 { |
| 105 | childType = "Input" |
| 106 | } |
| 107 | root.Children = append(root.Children, &Link{Type: childType, Dest: child}) |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | return root |
| 112 | } |
| 113 | |
| 114 | type QueryPlanRow struct { |
| 115 | ID int32 |
no outgoing calls