forked from alibaba/AliSQL
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathempty_result_pullup.cpp
More file actions
96 lines (91 loc) · 2.94 KB
/
empty_result_pullup.cpp
File metadata and controls
96 lines (91 loc) · 2.94 KB
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include "duckdb/optimizer/empty_result_pullup.hpp"
#include "duckdb/common/enums/logical_operator_type.hpp"
#include "duckdb/planner/operator/logical_comparison_join.hpp"
#include "duckdb/planner/operator/logical_empty_result.hpp"
#include "duckdb/planner/operator/logical_any_join.hpp"
namespace duckdb {
unique_ptr<LogicalOperator> EmptyResultPullup::PullUpEmptyJoinChildren(unique_ptr<LogicalOperator> op) {
JoinType join_type = JoinType::INVALID;
D_ASSERT(op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN ||
op->type == LogicalOperatorType::LOGICAL_ANY_JOIN || op->type == LogicalOperatorType::LOGICAL_DELIM_JOIN ||
op->type == LogicalOperatorType::LOGICAL_EXCEPT);
switch (op->type) {
case LogicalOperatorType::LOGICAL_DELIM_JOIN:
case LogicalOperatorType::LOGICAL_COMPARISON_JOIN:
join_type = op->Cast<LogicalComparisonJoin>().join_type;
break;
case LogicalOperatorType::LOGICAL_ANY_JOIN:
join_type = op->Cast<LogicalAnyJoin>().join_type;
break;
case LogicalOperatorType::LOGICAL_EXCEPT:
join_type = JoinType::ANTI;
break;
case LogicalOperatorType::LOGICAL_INTERSECT:
join_type = JoinType::SEMI;
break;
default:
break;
}
switch (join_type) {
case JoinType::SEMI:
case JoinType::INNER: {
for (auto &child : op->children) {
if (child->type == LogicalOperatorType::LOGICAL_EMPTY_RESULT) {
op = make_uniq<LogicalEmptyResult>(std::move(op));
break;
}
}
break;
}
// TODO: For ANTI joins, if the right child is empty, you can replace the whole join with
// the left child
case JoinType::ANTI:
case JoinType::MARK:
case JoinType::SINGLE:
case JoinType::LEFT: {
if (op->children[0]->type == LogicalOperatorType::LOGICAL_EMPTY_RESULT) {
op = make_uniq<LogicalEmptyResult>(std::move(op));
}
break;
}
default:
break;
}
return op;
}
unique_ptr<LogicalOperator> EmptyResultPullup::Optimize(unique_ptr<LogicalOperator> op) {
for (idx_t i = 0; i < op->children.size(); i++) {
op->children[i] = Optimize(std::move(op->children[i]));
}
switch (op->type) {
case LogicalOperatorType::LOGICAL_PROJECTION:
case LogicalOperatorType::LOGICAL_FILTER:
case LogicalOperatorType::LOGICAL_DISTINCT:
case LogicalOperatorType::LOGICAL_WINDOW:
case LogicalOperatorType::LOGICAL_MATERIALIZED_CTE:
case LogicalOperatorType::LOGICAL_GET:
case LogicalOperatorType::LOGICAL_INTERSECT:
case LogicalOperatorType::LOGICAL_PIVOT:
case LogicalOperatorType::LOGICAL_ASOF_JOIN:
case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: {
for (auto &child : op->children) {
if (child->type == LogicalOperatorType::LOGICAL_EMPTY_RESULT) {
op = make_uniq<LogicalEmptyResult>(std::move(op));
break;
}
}
return op;
}
case LogicalOperatorType::LOGICAL_EXCEPT:
case LogicalOperatorType::LOGICAL_ANY_JOIN:
case LogicalOperatorType::LOGICAL_DELIM_JOIN:
case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: {
op = PullUpEmptyJoinChildren(std::move(op));
break;
}
default:
break;
}
return op;
}
} // namespace duckdb