1 | #include "duckdb/optimizer/filter_pushdown.hpp" |
---|---|
2 | #include "duckdb/planner/operator/logical_any_join.hpp" |
3 | #include "duckdb/planner/operator/logical_comparison_join.hpp" |
4 | #include "duckdb/planner/operator/logical_cross_product.hpp" |
5 | #include "duckdb/planner/operator/logical_empty_result.hpp" |
6 | |
7 | using namespace duckdb; |
8 | using namespace std; |
9 | |
10 | using Filter = FilterPushdown::Filter; |
11 | |
12 | unique_ptr<LogicalOperator> FilterPushdown::PushdownInnerJoin(unique_ptr<LogicalOperator> op, |
13 | unordered_set<idx_t> &left_bindings, |
14 | unordered_set<idx_t> &right_bindings) { |
15 | auto &join = (LogicalJoin &)*op; |
16 | assert(join.join_type == JoinType::INNER); |
17 | assert(op->type != LogicalOperatorType::DELIM_JOIN); |
18 | // inner join: gather all the conditions of the inner join and add to the filter list |
19 | if (op->type == LogicalOperatorType::ANY_JOIN) { |
20 | auto &any_join = (LogicalAnyJoin &)join; |
21 | // any join: only one filter to add |
22 | if (AddFilter(move(any_join.condition)) == FilterResult::UNSATISFIABLE) { |
23 | // filter statically evaluates to false, strip tree |
24 | return make_unique<LogicalEmptyResult>(move(op)); |
25 | } |
26 | } else { |
27 | // comparison join |
28 | assert(op->type == LogicalOperatorType::COMPARISON_JOIN); |
29 | auto &comp_join = (LogicalComparisonJoin &)join; |
30 | // turn the conditions into filters |
31 | for (idx_t i = 0; i < comp_join.conditions.size(); i++) { |
32 | auto condition = JoinCondition::CreateExpression(move(comp_join.conditions[i])); |
33 | if (AddFilter(move(condition)) == FilterResult::UNSATISFIABLE) { |
34 | // filter statically evaluates to false, strip tree |
35 | return make_unique<LogicalEmptyResult>(move(op)); |
36 | } |
37 | } |
38 | } |
39 | GenerateFilters(); |
40 | |
41 | // turn the inner join into a cross product |
42 | auto cross_product = make_unique<LogicalCrossProduct>(); |
43 | cross_product->children.push_back(move(op->children[0])); |
44 | cross_product->children.push_back(move(op->children[1])); |
45 | // then push down cross product |
46 | return PushdownCrossProduct(move(cross_product)); |
47 | } |
48 |