| 1 | #include "duckdb/execution/operator/set/physical_union.hpp" |
| 2 | |
| 3 | #include "duckdb/common/vector_operations/vector_operations.hpp" |
| 4 | |
| 5 | using namespace duckdb; |
| 6 | using namespace std; |
| 7 | |
| 8 | class PhysicalUnionOperatorState : public PhysicalOperatorState { |
| 9 | public: |
| 10 | PhysicalUnionOperatorState() : PhysicalOperatorState(nullptr), top_done(false) { |
| 11 | } |
| 12 | unique_ptr<PhysicalOperatorState> top_state; |
| 13 | unique_ptr<PhysicalOperatorState> bottom_state; |
| 14 | bool top_done = false; |
| 15 | }; |
| 16 | |
| 17 | PhysicalUnion::PhysicalUnion(LogicalOperator &op, unique_ptr<PhysicalOperator> top, unique_ptr<PhysicalOperator> bottom) |
| 18 | : PhysicalOperator(PhysicalOperatorType::UNION, op.types) { |
| 19 | children.push_back(move(top)); |
| 20 | children.push_back(move(bottom)); |
| 21 | } |
| 22 | |
| 23 | // first exhaust top, then exhaust bottom. state to remember which. |
| 24 | void PhysicalUnion::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) { |
| 25 | auto state = reinterpret_cast<PhysicalUnionOperatorState *>(state_); |
| 26 | if (!state->top_done) { |
| 27 | children[0]->GetChunk(context, chunk, state->top_state.get()); |
| 28 | if (chunk.size() == 0) { |
| 29 | state->top_done = true; |
| 30 | } |
| 31 | } |
| 32 | if (state->top_done) { |
| 33 | children[1]->GetChunk(context, chunk, state->bottom_state.get()); |
| 34 | } |
| 35 | if (chunk.size() == 0) { |
| 36 | state->finished = true; |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | unique_ptr<PhysicalOperatorState> PhysicalUnion::GetOperatorState() { |
| 41 | auto state = make_unique<PhysicalUnionOperatorState>(); |
| 42 | state->top_state = children[0]->GetOperatorState(); |
| 43 | state->bottom_state = children[1]->GetOperatorState(); |
| 44 | return (move(state)); |
| 45 | } |
| 46 | |