| 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 | 
