1#include "duckdb/execution/operator/set/physical_recursive_cte.hpp"
2#include "duckdb/execution/operator/scan/physical_chunk_scan.hpp"
3#include "duckdb/execution/physical_plan_generator.hpp"
4#include "duckdb/planner/expression/bound_reference_expression.hpp"
5#include "duckdb/planner/operator/logical_recursive_cte.hpp"
6#include "duckdb/planner/operator/logical_cteref.hpp"
7
8using namespace duckdb;
9using namespace std;
10
11unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalRecursiveCTE &op) {
12 assert(op.children.size() == 2);
13
14 // Create the working_table that the PhysicalRecursiveCTE will use for evaluation.
15 auto working_table = std::make_shared<ChunkCollection>();
16
17 // Add the ChunkCollection to the context of this PhysicalPlanGenerator
18 rec_ctes[op.table_index] = working_table;
19
20 auto left = CreatePlan(*op.children[0]);
21 auto right = CreatePlan(*op.children[1]);
22
23 auto cte = make_unique<PhysicalRecursiveCTE>(op, op.union_all, move(left), move(right));
24 cte->working_table = working_table;
25
26 return move(cte);
27}
28
29unique_ptr<PhysicalOperator> PhysicalPlanGenerator::CreatePlan(LogicalCTERef &op) {
30 assert(op.children.size() == 0);
31
32 auto chunk_scan = make_unique<PhysicalChunkScan>(op.types, PhysicalOperatorType::CHUNK_SCAN);
33
34 // CreatePlan of a LogicalRecursiveCTE must have happened before.
35 auto cte = rec_ctes.find(op.cte_index);
36 if (cte == rec_ctes.end()) {
37 throw Exception("Referenced recursive CTE does not exist.");
38 }
39 chunk_scan->collection = cte->second.get();
40 return move(chunk_scan);
41}
42