1#include "duckdb/execution/operator/join/physical_cross_product.hpp"
2#include "duckdb/execution/operator/join/physical_hash_join.hpp"
3#include "duckdb/execution/operator/join/physical_nested_loop_join.hpp"
4#include "duckdb/execution/operator/join/physical_piecewise_merge_join.hpp"
5#include "duckdb/execution/physical_plan_generator.hpp"
6#include "duckdb/planner/operator/logical_comparison_join.hpp"
7
8using namespace duckdb;
9using namespace std;
10
11unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalComparisonJoin &op) {
12 // now visit the children
13 assert(op.children.size() == 2);
14
15 auto left = CreatePlan(*op.children[0]);
16 auto right = CreatePlan(*op.children[1]);
17 assert(left && right);
18
19 if (op.conditions.size() == 0) {
20 // no conditions: insert a cross product
21 return make_unique<PhysicalCrossProduct>(op, move(left), move(right));
22 }
23
24 bool has_equality = false;
25 bool has_inequality = false;
26 bool has_null_equal_conditions = false;
27 for (auto &cond : op.conditions) {
28 if (cond.comparison == ExpressionType::COMPARE_EQUAL) {
29 has_equality = true;
30 }
31 if (cond.comparison == ExpressionType::COMPARE_NOTEQUAL) {
32 has_inequality = true;
33 }
34 if (cond.null_values_are_equal) {
35 has_null_equal_conditions = true;
36 assert(cond.comparison == ExpressionType::COMPARE_EQUAL);
37 }
38 }
39 unique_ptr<PhysicalOperator> plan;
40 if (has_equality) {
41 // equality join: use hash join
42 plan = make_unique<PhysicalHashJoin>(context, op, move(left), move(right), move(op.conditions), op.join_type,
43 op.left_projection_map, op.right_projection_map);
44 } else {
45 assert(!has_null_equal_conditions); // don't support this for anything but hash joins for now
46 if (op.conditions.size() == 1 && (op.join_type == JoinType::MARK || op.join_type == JoinType::INNER) &&
47 !has_inequality) {
48 // range join: use piecewise merge join
49 plan =
50 make_unique<PhysicalPiecewiseMergeJoin>(op, move(left), move(right), move(op.conditions), op.join_type);
51 } else {
52 // inequality join: use nested loop
53 plan = make_unique<PhysicalNestedLoopJoin>(op, move(left), move(right), move(op.conditions), op.join_type);
54 }
55 }
56 return plan;
57}
58