1#include "duckdb/planner/operator/logical_insert.hpp"
2
3#include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp"
4#include "duckdb/common/field_writer.hpp"
5#include "duckdb/main/config.hpp"
6#include "duckdb/parser/parsed_data/create_table_info.hpp"
7
8namespace duckdb {
9
10LogicalInsert::LogicalInsert(TableCatalogEntry &table, idx_t table_index)
11 : LogicalOperator(LogicalOperatorType::LOGICAL_INSERT), table(table), table_index(table_index), return_chunk(false),
12 action_type(OnConflictAction::THROW) {
13}
14
15void LogicalInsert::Serialize(FieldWriter &writer) const {
16 writer.WriteField<idx_t>(element: insert_values.size());
17 for (auto &entry : insert_values) {
18 writer.WriteSerializableList(elements: entry);
19 }
20
21 writer.WriteList<idx_t>(elements: column_index_map);
22 writer.WriteRegularSerializableList(elements: expected_types);
23 table.Serialize(serializer&: writer.GetSerializer());
24 writer.WriteField(element: table_index);
25 writer.WriteField(element: return_chunk);
26 writer.WriteSerializableList(elements: bound_defaults);
27 writer.WriteField(element: action_type);
28 writer.WriteRegularSerializableList(elements: expected_set_types);
29 writer.WriteList<column_t>(elements: on_conflict_filter);
30 writer.WriteOptional(element: on_conflict_condition);
31 writer.WriteOptional(element: do_update_condition);
32 writer.WriteIndexList(elements: set_columns);
33 writer.WriteRegularSerializableList(elements: set_types);
34 writer.WriteField(element: excluded_table_index);
35 writer.WriteList<column_t>(elements: columns_to_fetch);
36 writer.WriteList<column_t>(elements: source_columns);
37 writer.WriteSerializableList<Expression>(elements: expressions);
38}
39
40unique_ptr<LogicalOperator> LogicalInsert::Deserialize(LogicalDeserializationState &state, FieldReader &reader) {
41 auto &context = state.gstate.context;
42 auto insert_values_size = reader.ReadRequired<idx_t>();
43 vector<vector<unique_ptr<Expression>>> insert_values;
44 for (idx_t i = 0; i < insert_values_size; ++i) {
45 insert_values.push_back(x: reader.ReadRequiredSerializableList<Expression>(args&: state.gstate));
46 }
47
48 auto column_index_map = reader.ReadRequiredList<idx_t, physical_index_vector_t<idx_t>>();
49 auto expected_types = reader.ReadRequiredSerializableList<LogicalType, LogicalType>();
50 auto info = TableCatalogEntry::Deserialize(source&: reader.GetSource(), context);
51 auto table_index = reader.ReadRequired<idx_t>();
52 auto return_chunk = reader.ReadRequired<bool>();
53 auto bound_defaults = reader.ReadRequiredSerializableList<Expression>(args&: state.gstate);
54 auto action_type = reader.ReadRequired<OnConflictAction>();
55 auto expected_set_types = reader.ReadRequiredSerializableList<LogicalType, LogicalType>();
56 auto on_conflict_filter = reader.ReadRequiredSet<column_t, unordered_set<column_t>>();
57 auto on_conflict_condition = reader.ReadOptional<Expression>(default_value: nullptr, args&: state.gstate);
58 auto do_update_condition = reader.ReadOptional<Expression>(default_value: nullptr, args&: state.gstate);
59 auto set_columns = reader.ReadRequiredIndexList<PhysicalIndex>();
60 auto set_types = reader.ReadRequiredSerializableList<LogicalType, LogicalType>();
61 auto excluded_table_index = reader.ReadRequired<idx_t>();
62 auto columns_to_fetch = reader.ReadRequiredList<column_t>();
63 auto source_columns = reader.ReadRequiredList<column_t>();
64 auto expressions = reader.ReadRequiredSerializableList<Expression>(args&: state.gstate);
65
66 auto &catalog = Catalog::GetCatalog(context, catalog_name: info->catalog);
67
68 auto &table_catalog_entry = catalog.GetEntry<TableCatalogEntry>(context, schema_name: info->schema, name: info->table);
69 auto result = make_uniq<LogicalInsert>(args&: table_catalog_entry, args&: table_index);
70 result->type = state.type;
71 result->return_chunk = return_chunk;
72 result->insert_values = std::move(insert_values);
73 result->column_index_map = column_index_map;
74 result->expected_types = expected_types;
75 result->bound_defaults = std::move(bound_defaults);
76 result->action_type = action_type;
77 result->expected_set_types = std::move(expected_set_types);
78 result->on_conflict_filter = std::move(on_conflict_filter);
79 result->on_conflict_condition = std::move(on_conflict_condition);
80 result->do_update_condition = std::move(do_update_condition);
81 result->set_columns = std::move(set_columns);
82 result->set_types = std::move(set_types);
83 result->excluded_table_index = excluded_table_index;
84 result->columns_to_fetch = std::move(columns_to_fetch);
85 result->source_columns = std::move(source_columns);
86 result->expressions = std::move(expressions);
87 return std::move(result);
88}
89
90idx_t LogicalInsert::EstimateCardinality(ClientContext &context) {
91 return return_chunk ? LogicalOperator::EstimateCardinality(context) : 1;
92}
93
94vector<idx_t> LogicalInsert::GetTableIndex() const {
95 return vector<idx_t> {table_index};
96}
97
98vector<ColumnBinding> LogicalInsert::GetColumnBindings() {
99 if (return_chunk) {
100 return GenerateColumnBindings(table_idx: table_index, column_count: table.GetTypes().size());
101 }
102 return {ColumnBinding(0, 0)};
103}
104
105void LogicalInsert::ResolveTypes() {
106 if (return_chunk) {
107 types = table.GetTypes();
108 } else {
109 types.emplace_back(args: LogicalType::BIGINT);
110 }
111}
112
113string LogicalInsert::GetName() const {
114#ifdef DEBUG
115 if (DBConfigOptions::debug_print_bindings) {
116 return LogicalOperator::GetName() + StringUtil::Format(" #%llu", table_index);
117 }
118#endif
119 return LogicalOperator::GetName();
120}
121
122} // namespace duckdb
123