1 | #include "duckdb/optimizer/filter_pushdown.hpp" |
2 | #include "duckdb/planner/operator/logical_comparison_join.hpp" |
3 | #include "duckdb/planner/operator/logical_cross_product.hpp" |
4 | |
5 | using namespace duckdb; |
6 | using namespace std; |
7 | |
8 | using Filter = FilterPushdown::Filter; |
9 | |
10 | unique_ptr<LogicalOperator> FilterPushdown::PushdownCrossProduct(unique_ptr<LogicalOperator> op) { |
11 | assert(op->type == LogicalOperatorType::CROSS_PRODUCT); |
12 | FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer); |
13 | vector<unique_ptr<Expression>> join_conditions; |
14 | unordered_set<idx_t> left_bindings, right_bindings; |
15 | if (filters.size() > 0) { |
16 | // check to see into which side we should push the filters |
17 | // first get the LHS and RHS bindings |
18 | LogicalJoin::GetTableReferences(*op->children[0], left_bindings); |
19 | LogicalJoin::GetTableReferences(*op->children[1], right_bindings); |
20 | // now check the set of filters |
21 | for (auto &f : filters) { |
22 | auto side = JoinSide::GetJoinSide(f->bindings, left_bindings, right_bindings); |
23 | if (side == JoinSide::LEFT) { |
24 | // bindings match left side: push into left |
25 | left_pushdown.filters.push_back(move(f)); |
26 | } else if (side == JoinSide::RIGHT) { |
27 | // bindings match right side: push into right |
28 | right_pushdown.filters.push_back(move(f)); |
29 | } else { |
30 | assert(side == JoinSide::BOTH); |
31 | // bindings match both: turn into join condition |
32 | join_conditions.push_back(move(f->filter)); |
33 | } |
34 | } |
35 | } |
36 | op->children[0] = left_pushdown.Rewrite(move(op->children[0])); |
37 | op->children[1] = right_pushdown.Rewrite(move(op->children[1])); |
38 | |
39 | if (join_conditions.size() > 0) { |
40 | // join conditions found: turn into inner join |
41 | return LogicalComparisonJoin::CreateJoin(JoinType::INNER, move(op->children[0]), move(op->children[1]), |
42 | left_bindings, right_bindings, join_conditions); |
43 | } else { |
44 | // no join conditions found: keep as cross product |
45 | return op; |
46 | } |
47 | } |
48 | |