1#include "duckdb/execution/operator/projection/physical_projection.hpp"
2#include "duckdb/parallel/thread_context.hpp"
3#include "duckdb/execution/expression_executor.hpp"
4#include "duckdb/planner/expression/bound_reference_expression.hpp"
5
6namespace duckdb {
7
8class ProjectionState : public OperatorState {
9public:
10 explicit ProjectionState(ExecutionContext &context, const vector<unique_ptr<Expression>> &expressions)
11 : executor(context.client, expressions) {
12 }
13
14 ExpressionExecutor executor;
15
16public:
17 void Finalize(const PhysicalOperator &op, ExecutionContext &context) override {
18 context.thread.profiler.Flush(phys_op: op, expression_executor&: executor, name: "projection", id: 0);
19 }
20};
21
22PhysicalProjection::PhysicalProjection(vector<LogicalType> types, vector<unique_ptr<Expression>> select_list,
23 idx_t estimated_cardinality)
24 : PhysicalOperator(PhysicalOperatorType::PROJECTION, std::move(types), estimated_cardinality),
25 select_list(std::move(select_list)) {
26}
27
28OperatorResultType PhysicalProjection::Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk,
29 GlobalOperatorState &gstate, OperatorState &state_p) const {
30 auto &state = state_p.Cast<ProjectionState>();
31 state.executor.Execute(input, result&: chunk);
32 return OperatorResultType::NEED_MORE_INPUT;
33}
34
35unique_ptr<OperatorState> PhysicalProjection::GetOperatorState(ExecutionContext &context) const {
36 return make_uniq<ProjectionState>(args&: context, args: select_list);
37}
38
39unique_ptr<PhysicalOperator>
40PhysicalProjection::CreateJoinProjection(vector<LogicalType> proj_types, const vector<LogicalType> &lhs_types,
41 const vector<LogicalType> &rhs_types, const vector<idx_t> &left_projection_map,
42 const vector<idx_t> &right_projection_map, const idx_t estimated_cardinality) {
43
44 vector<unique_ptr<Expression>> proj_selects;
45 proj_selects.reserve(n: proj_types.size());
46
47 if (left_projection_map.empty()) {
48 for (storage_t i = 0; i < lhs_types.size(); ++i) {
49 proj_selects.emplace_back(args: make_uniq<BoundReferenceExpression>(args: lhs_types[i], args&: i));
50 }
51 } else {
52 for (auto i : left_projection_map) {
53 proj_selects.emplace_back(args: make_uniq<BoundReferenceExpression>(args: lhs_types[i], args&: i));
54 }
55 }
56 const auto left_cols = lhs_types.size();
57
58 if (right_projection_map.empty()) {
59 for (storage_t i = 0; i < rhs_types.size(); ++i) {
60 proj_selects.emplace_back(args: make_uniq<BoundReferenceExpression>(args: rhs_types[i], args: left_cols + i));
61 }
62
63 } else {
64 for (auto i : right_projection_map) {
65 proj_selects.emplace_back(args: make_uniq<BoundReferenceExpression>(args: rhs_types[i], args: left_cols + i));
66 }
67 }
68
69 return make_uniq<PhysicalProjection>(args: std::move(proj_types), args: std::move(proj_selects), args: estimated_cardinality);
70}
71
72string PhysicalProjection::ParamsToString() const {
73 string extra_info;
74 for (auto &expr : select_list) {
75 extra_info += expr->GetName() + "\n";
76 }
77 return extra_info;
78}
79
80} // namespace duckdb
81