ClickHouse
65 строк · 2.1 Кб
1#include <Processors/QueryPlan/Optimizations/Optimizations.h>
2#include <Processors/QueryPlan/UnionStep.h>
3#include <Processors/QueryPlan/ExpressionStep.h>
4#include <Interpreters/ActionsDAG.h>
5
6namespace DB::QueryPlanOptimizations
7{
8
9size_t tryLiftUpUnion(QueryPlan::Node * parent_node, QueryPlan::Nodes & nodes)
10{
11if (parent_node->children.empty())
12return 0;
13
14QueryPlan::Node * child_node = parent_node->children.front();
15auto & parent = parent_node->step;
16auto & child = child_node->step;
17
18auto * union_step = typeid_cast<UnionStep *>(child.get());
19if (!union_step)
20return 0;
21
22if (auto * expression = typeid_cast<ExpressionStep *>(parent.get()))
23{
24/// Union does not change header.
25/// We can push down expression and update header.
26auto union_input_streams = child->getInputStreams();
27for (auto & input_stream : union_input_streams)
28input_stream.header = expression->getOutputStream().header;
29
30/// - Something
31/// Expression - Union - Something
32/// - Something
33
34child = std::make_unique<UnionStep>(union_input_streams, union_step->getMaxThreads());
35
36std::swap(parent, child);
37std::swap(parent_node->children, child_node->children);
38std::swap(parent_node->children.front(), child_node->children.front());
39
40/// - Expression - Something
41/// Union - Something
42/// - Something
43
44for (size_t i = 1; i < parent_node->children.size(); ++i)
45{
46auto & expr_node = nodes.emplace_back();
47expr_node.children.push_back(parent_node->children[i]);
48parent_node->children[i] = &expr_node;
49
50expr_node.step = std::make_unique<ExpressionStep>(
51expr_node.children.front()->step->getOutputStream(),
52expression->getExpression()->clone());
53}
54
55/// - Expression - Something
56/// Union - Expression - Something
57/// - Expression - Something
58
59return 3;
60}
61
62return 0;
63}
64
65}
66