1#include "duckdb/execution/operator/persistent/physical_insert.hpp"
2
3#include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp"
4#include "duckdb/common/types/chunk_collection.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
12void PhysicalInsert::GetChunkInternal(ClientContext &context, DataChunk &chunk, PhysicalOperatorState *state) {
13
14 int64_t insert_count = 0;
15 // create the chunk to insert from
16 DataChunk insert_chunk;
17 auto types = table->GetTypes();
18
19 // initialize executor for bound default expressions
20 ExpressionExecutor default_executor(bound_defaults);
21
22 insert_chunk.Initialize(types);
23 while (true) {
24 // scan the children for chunks to insert
25 children[0]->GetChunk(context, state->child_chunk, state->child_state.get());
26 if (state->child_chunk.size() == 0) {
27 break;
28 }
29 auto &chunk = state->child_chunk;
30
31 chunk.Normalify();
32 default_executor.SetChunk(chunk);
33
34 insert_chunk.Reset();
35 insert_chunk.SetCardinality(chunk);
36 if (column_index_map.size() > 0) {
37 // columns specified by the user, use column_index_map
38 for (idx_t i = 0; i < table->columns.size(); i++) {
39 if (column_index_map[i] == INVALID_INDEX) {
40 // insert default value
41 default_executor.ExecuteExpression(i, insert_chunk.data[i]);
42 } else {
43 // get value from child chunk
44 assert((idx_t)column_index_map[i] < chunk.column_count());
45 assert(insert_chunk.data[i].type == chunk.data[column_index_map[i]].type);
46 insert_chunk.data[i].Reference(chunk.data[column_index_map[i]]);
47 }
48 }
49 } else {
50 // no columns specified, just append directly
51 for (idx_t i = 0; i < insert_chunk.column_count(); i++) {
52 assert(insert_chunk.data[i].type == chunk.data[i].type);
53 insert_chunk.data[i].Reference(chunk.data[i]);
54 }
55 }
56 table->storage->Append(*table, context, insert_chunk);
57 insert_count += chunk.size();
58 }
59
60 chunk.SetCardinality(1);
61 chunk.SetValue(0, 0, Value::BIGINT(insert_count));
62
63 state->finished = true;
64}
65