| 1017 | // } |
| 1018 | |
| 1019 | QueryPlan QueryPlan::extractSubplan(Node * root, Nodes & nodes) |
| 1020 | { |
| 1021 | std::unordered_set<Node *> used; |
| 1022 | std::stack<Node *> stack; |
| 1023 | |
| 1024 | stack.push(root); |
| 1025 | used.insert(root); |
| 1026 | while (!stack.empty()) |
| 1027 | { |
| 1028 | const auto * node = stack.top(); |
| 1029 | stack.pop(); |
| 1030 | |
| 1031 | for (auto * child : node->children) |
| 1032 | { |
| 1033 | used.insert(child); |
| 1034 | stack.push(child); |
| 1035 | } |
| 1036 | } |
| 1037 | |
| 1038 | QueryPlan new_plan; |
| 1039 | new_plan.root = root; |
| 1040 | |
| 1041 | auto it = nodes.begin(); |
| 1042 | while (it != nodes.end()) |
| 1043 | { |
| 1044 | auto curr = it; |
| 1045 | ++it; |
| 1046 | |
| 1047 | if (used.contains(&*curr)) |
| 1048 | new_plan.nodes.splice(new_plan.nodes.end(), nodes, curr); |
| 1049 | } |
| 1050 | |
| 1051 | // { |
| 1052 | // WriteBufferFromOwnString buf; |
| 1053 | // new_plan.explainPlan(buf, {.header=true, .actions=true}); |
| 1054 | // std::cerr << buf.stringView() << std::endl; |
| 1055 | // } |
| 1056 | |
| 1057 | // validatePlan(new_plan.root, new_plan.nodes); |
| 1058 | |
| 1059 | return new_plan; |
| 1060 | } |
| 1061 | |
| 1062 | std::pair<QueryPlan::Nodes, QueryPlanResourceHolder> QueryPlan::detachNodesAndResources(QueryPlan && plan) |
| 1063 | { |