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