| 456 | } |
| 457 | |
| 458 | void validateTreeSize(const QueryTreeNodePtr & node, |
| 459 | size_t max_size, |
| 460 | std::unordered_map<QueryTreeNodePtr, size_t> & node_to_tree_size) |
| 461 | { |
| 462 | size_t tree_size = 0; |
| 463 | std::vector<std::pair<QueryTreeNodePtr, bool>> nodes_to_process; |
| 464 | nodes_to_process.emplace_back(node, false); |
| 465 | |
| 466 | while (!nodes_to_process.empty()) |
| 467 | { |
| 468 | const auto [node_to_process, processed_children] = nodes_to_process.back(); |
| 469 | nodes_to_process.pop_back(); |
| 470 | |
| 471 | if (processed_children) |
| 472 | { |
| 473 | ++tree_size; |
| 474 | |
| 475 | size_t subtree_size = 1; |
| 476 | for (const auto & node_to_process_child : node_to_process->getChildren()) |
| 477 | { |
| 478 | if (!node_to_process_child) |
| 479 | continue; |
| 480 | |
| 481 | subtree_size += node_to_tree_size[node_to_process_child]; |
| 482 | } |
| 483 | |
| 484 | auto * constant_node = node_to_process->as<ConstantNode>(); |
| 485 | if (constant_node && constant_node->hasSourceExpression()) |
| 486 | subtree_size += node_to_tree_size[constant_node->getSourceExpression()]; |
| 487 | |
| 488 | node_to_tree_size.emplace(node_to_process, subtree_size); |
| 489 | continue; |
| 490 | } |
| 491 | |
| 492 | auto node_to_size_it = node_to_tree_size.find(node_to_process); |
| 493 | if (node_to_size_it != node_to_tree_size.end()) |
| 494 | { |
| 495 | tree_size += node_to_size_it->second; |
| 496 | continue; |
| 497 | } |
| 498 | |
| 499 | nodes_to_process.emplace_back(node_to_process, true); |
| 500 | |
| 501 | for (const auto & node_to_process_child : node_to_process->getChildren()) |
| 502 | { |
| 503 | if (!node_to_process_child) |
| 504 | continue; |
| 505 | |
| 506 | nodes_to_process.emplace_back(node_to_process_child, false); |
| 507 | } |
| 508 | |
| 509 | auto * constant_node = node_to_process->as<ConstantNode>(); |
| 510 | if (constant_node && constant_node->hasSourceExpression()) |
| 511 | nodes_to_process.emplace_back(constant_node->getSourceExpression(), false); |
| 512 | } |
| 513 | |
| 514 | if (tree_size > max_size) |
| 515 | throw Exception(ErrorCodes::BAD_ARGUMENTS, |
no test coverage detected