1#include "duckdb/execution/operator/order/physical_order.hpp"
2
3#include "duckdb/common/assert.hpp"
4#include "duckdb/common/value_operations/value_operations.hpp"
5#include "duckdb/common/vector_operations/vector_operations.hpp"
6#include "duckdb/execution/expression_executor.hpp"
7#include "duckdb/storage/data_table.hpp"
8
9using namespace duckdb;
10using namespace std;
11
12class PhysicalOrderOperatorState : public PhysicalOperatorState {
13public:
14 PhysicalOrderOperatorState(PhysicalOperator *child) : PhysicalOperatorState(child), position(0) {
15 }
16
17 idx_t position;
18 ChunkCollection sorted_data;
19 unique_ptr<idx_t[]> sorted_vector;
20};
21
22void PhysicalOrder::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state_) {
23 auto state = reinterpret_cast<PhysicalOrderOperatorState *>(state_);
24 ChunkCollection &big_data = state->sorted_data;
25 if (state->position == 0) {
26 // first concatenate all the data of the child chunks
27 do {
28 children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
29 big_data.Append(state->child_chunk);
30 } while (state->child_chunk.size() != 0);
31
32 // now perform the actual ordering of the data
33 // compute the sorting columns from the input data
34 ExpressionExecutor executor;
35 vector<TypeId> sort_types;
36 vector<OrderType> order_types;
37 for (idx_t i = 0; i < orders.size(); i++) {
38 auto &expr = orders[i].expression;
39 sort_types.push_back(expr->return_type);
40 order_types.push_back(orders[i].type);
41 executor.AddExpression(*expr);
42 }
43
44 ChunkCollection sort_collection;
45 for (idx_t i = 0; i < big_data.chunks.size(); i++) {
46 DataChunk sort_chunk;
47 sort_chunk.Initialize(sort_types);
48
49 executor.Execute(*big_data.chunks[i], sort_chunk);
50 sort_collection.Append(sort_chunk);
51 }
52
53 assert(sort_collection.count == big_data.count);
54
55 // now perform the actual sort
56 state->sorted_vector = unique_ptr<idx_t[]>(new idx_t[sort_collection.count]);
57 sort_collection.Sort(order_types, state->sorted_vector.get());
58 }
59
60 if (state->position >= big_data.count) {
61 return;
62 }
63
64 big_data.MaterializeSortedChunk(chunk, state->sorted_vector.get(), state->position);
65 state->position += STANDARD_VECTOR_SIZE;
66}
67
68unique_ptr<PhysicalOperatorState> PhysicalOrder::GetOperatorState() {
69 return make_unique<PhysicalOrderOperatorState>(children[0].get());
70}
71