MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / cloneAndReplace

Method cloneAndReplace

src/Analyzer/IQueryTreeNode.cpp:244–337  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

242}
243
244QueryTreeNodePtr IQueryTreeNode::cloneAndReplace(const ReplacementMap & replacement_map) const
245{
246 /** Clone tree with this node as root.
247 *
248 * Algorithm
249 * For each node we clone state and also create mapping old pointer to new pointer.
250 * For each cloned node we update weak pointers array.
251 *
252 * After that we can update pointer in weak pointers array using old pointer to new pointer mapping.
253 */
254 std::unordered_map<const IQueryTreeNode *, QueryTreeNodePtr> old_pointer_to_new_pointer;
255 std::vector<QueryTreeNodeWeakPtr *> weak_pointers_to_update_after_clone;
256
257 QueryTreeNodePtr result_cloned_node_place;
258
259 std::vector<std::pair<const IQueryTreeNode *, QueryTreeNodePtr *>> nodes_to_clone;
260 nodes_to_clone.emplace_back(this, &result_cloned_node_place);
261
262 while (!nodes_to_clone.empty())
263 {
264 const auto [node_to_clone, place_for_cloned_node] = nodes_to_clone.back();
265 nodes_to_clone.pop_back();
266
267 auto already_cloned_node_it = old_pointer_to_new_pointer.find(node_to_clone);
268 if (already_cloned_node_it != old_pointer_to_new_pointer.end())
269 {
270 *place_for_cloned_node = already_cloned_node_it->second;
271 continue;
272 }
273
274 auto it = replacement_map.find(node_to_clone);
275 auto node_clone = it != replacement_map.end() ? it->second : node_to_clone->cloneImpl();
276 *place_for_cloned_node = node_clone;
277
278 old_pointer_to_new_pointer.emplace(node_to_clone, node_clone);
279
280 if (it != replacement_map.end())
281 continue;
282
283 node_clone->original_ast = node_to_clone->original_ast;
284 node_clone->setAlias(node_to_clone->alias);
285 node_clone->parenthesized = node_to_clone->parenthesized;
286 node_clone->children = node_to_clone->children;
287 node_clone->weak_pointers = node_to_clone->weak_pointers;
288
289 for (auto & child : node_clone->children)
290 {
291 if (!child)
292 continue;
293
294 nodes_to_clone.emplace_back(child.get(), &child);
295 }
296
297 for (auto & weak_pointer : node_clone->weak_pointers)
298 {
299 weak_pointers_to_update_after_clone.push_back(&weak_pointer);
300 }
301 }

Calls 12

emplace_backMethod · 0.45
emptyMethod · 0.45
backMethod · 0.45
pop_backMethod · 0.45
findMethod · 0.45
endMethod · 0.45
cloneImplMethod · 0.45
emplaceMethod · 0.45
setAliasMethod · 0.45
getMethod · 0.45
push_backMethod · 0.45
lockMethod · 0.45

Tested by

no test coverage detected