1#include "duckdb/planner/expression/bound_cast_expression.hpp"
2#include "duckdb/planner/binder.hpp"
3#include "duckdb/planner/operator/logical_projection.hpp"
4#include "duckdb/planner/operator/logical_recursive_cte.hpp"
5#include "duckdb/planner/operator/logical_set_operation.hpp"
6#include "duckdb/planner/query_node/bound_recursive_cte_node.hpp"
7
8using namespace duckdb;
9using namespace std;
10
11unique_ptr<LogicalOperator> Binder::CreatePlan(BoundRecursiveCTENode &node) {
12 // Generate the logical plan for the left and right sides of the set operation
13 node.left_binder->plan_subquery = plan_subquery;
14 node.right_binder->plan_subquery = plan_subquery;
15
16 auto left_node = node.left_binder->CreatePlan(*node.left);
17 auto right_node = node.right_binder->CreatePlan(*node.right);
18
19 // check if there are any unplanned subqueries left in either child
20 has_unplanned_subqueries =
21 node.left_binder->has_unplanned_subqueries || node.right_binder->has_unplanned_subqueries;
22
23 // for both the left and right sides, cast them to the same types
24 left_node = CastLogicalOperatorToTypes(node.left->types, node.types, move(left_node));
25 right_node = CastLogicalOperatorToTypes(node.right->types, node.types, move(right_node));
26
27 if (node.right_binder->bind_context.cte_references[node.ctename] == 0) {
28 auto root = make_unique<LogicalSetOperation>(node.setop_index, node.types.size(), move(left_node),
29 move(right_node), LogicalOperatorType::UNION);
30 return VisitQueryNode(node, move(root));
31 }
32 auto root = make_unique<LogicalRecursiveCTE>(node.setop_index, node.types.size(), node.union_all, move(left_node),
33 move(right_node), LogicalOperatorType::RECURSIVE_CTE);
34
35 return VisitQueryNode(node, move(root));
36}
37