| 712 | } |
| 713 | |
| 714 | void QueryPlan::explainPipeline(WriteBuffer & buffer, const ExplainPipelineOptions & options) const |
| 715 | { |
| 716 | checkInitialized(); |
| 717 | |
| 718 | IQueryPlanStep::FormatSettings settings{ |
| 719 | .out = buffer, |
| 720 | .header_prefix = "", |
| 721 | .detail_prefix = "", |
| 722 | .write_header = options.header, |
| 723 | .compact_repeated_processor_chains = options.compact_repeated_processor_chains, |
| 724 | .pretty_names = {}, |
| 725 | .runtime_filter_names = {} |
| 726 | }; |
| 727 | |
| 728 | struct Frame |
| 729 | { |
| 730 | Node * node = {}; |
| 731 | size_t offset = 0; |
| 732 | bool is_description_printed = false; |
| 733 | size_t next_child = 0; |
| 734 | }; |
| 735 | |
| 736 | std::stack<Frame> stack; |
| 737 | stack.push(Frame{.node = root}); |
| 738 | |
| 739 | while (!stack.empty()) |
| 740 | { |
| 741 | auto & frame = stack.top(); |
| 742 | |
| 743 | if (!frame.is_description_printed) |
| 744 | { |
| 745 | settings.offset = frame.offset; |
| 746 | explainPipelineStep(*frame.node->step, settings, options.distributed); |
| 747 | frame.offset = settings.offset; |
| 748 | frame.is_description_printed = true; |
| 749 | } |
| 750 | |
| 751 | if (frame.next_child < frame.node->children.size()) |
| 752 | { |
| 753 | stack.push(Frame{frame.node->children[frame.next_child], frame.offset}); |
| 754 | ++frame.next_child; |
| 755 | } |
| 756 | else |
| 757 | stack.pop(); |
| 758 | } |
| 759 | } |
| 760 | |
| 761 | void QueryPlan::optimize(const QueryPlanOptimizationSettings & optimization_settings) |
| 762 | { |
no test coverage detected