1#include "duckdb/common/types/data_chunk.hpp"
2#include "duckdb/common/types/string_type.hpp"
3#include "duckdb/main/capi/capi_internal.hpp"
4
5#include <string.h>
6
7duckdb_data_chunk duckdb_create_data_chunk(duckdb_logical_type *ctypes, idx_t column_count) {
8 if (!ctypes) {
9 return nullptr;
10 }
11 duckdb::vector<duckdb::LogicalType> types;
12 for (idx_t i = 0; i < column_count; i++) {
13 auto ltype = reinterpret_cast<duckdb::LogicalType *>(ctypes[i]);
14 types.push_back(x: *ltype);
15 }
16
17 auto result = new duckdb::DataChunk();
18 result->Initialize(allocator&: duckdb::Allocator::DefaultAllocator(), types);
19 return reinterpret_cast<duckdb_data_chunk>(result);
20}
21
22void duckdb_destroy_data_chunk(duckdb_data_chunk *chunk) {
23 if (chunk && *chunk) {
24 auto dchunk = reinterpret_cast<duckdb::DataChunk *>(*chunk);
25 delete dchunk;
26 *chunk = nullptr;
27 }
28}
29
30void duckdb_data_chunk_reset(duckdb_data_chunk chunk) {
31 if (!chunk) {
32 return;
33 }
34 auto dchunk = reinterpret_cast<duckdb::DataChunk *>(chunk);
35 dchunk->Reset();
36}
37
38idx_t duckdb_data_chunk_get_column_count(duckdb_data_chunk chunk) {
39 if (!chunk) {
40 return 0;
41 }
42 auto dchunk = reinterpret_cast<duckdb::DataChunk *>(chunk);
43 return dchunk->ColumnCount();
44}
45
46duckdb_vector duckdb_data_chunk_get_vector(duckdb_data_chunk chunk, idx_t col_idx) {
47 if (!chunk || col_idx >= duckdb_data_chunk_get_column_count(chunk)) {
48 return nullptr;
49 }
50 auto dchunk = reinterpret_cast<duckdb::DataChunk *>(chunk);
51 return reinterpret_cast<duckdb_vector>(&dchunk->data[col_idx]);
52}
53
54idx_t duckdb_data_chunk_get_size(duckdb_data_chunk chunk) {
55 if (!chunk) {
56 return 0;
57 }
58 auto dchunk = reinterpret_cast<duckdb::DataChunk *>(chunk);
59 return dchunk->size();
60}
61
62void duckdb_data_chunk_set_size(duckdb_data_chunk chunk, idx_t size) {
63 if (!chunk) {
64 return;
65 }
66 auto dchunk = reinterpret_cast<duckdb::DataChunk *>(chunk);
67 dchunk->SetCardinality(size);
68}
69
70duckdb_logical_type duckdb_vector_get_column_type(duckdb_vector vector) {
71 if (!vector) {
72 return nullptr;
73 }
74 auto v = reinterpret_cast<duckdb::Vector *>(vector);
75 return reinterpret_cast<duckdb_logical_type>(new duckdb::LogicalType(v->GetType()));
76}
77
78void *duckdb_vector_get_data(duckdb_vector vector) {
79 if (!vector) {
80 return nullptr;
81 }
82 auto v = reinterpret_cast<duckdb::Vector *>(vector);
83 return duckdb::FlatVector::GetData(vector&: *v);
84}
85
86uint64_t *duckdb_vector_get_validity(duckdb_vector vector) {
87 if (!vector) {
88 return nullptr;
89 }
90 auto v = reinterpret_cast<duckdb::Vector *>(vector);
91 return duckdb::FlatVector::Validity(vector&: *v).GetData();
92}
93
94void duckdb_vector_ensure_validity_writable(duckdb_vector vector) {
95 if (!vector) {
96 return;
97 }
98 auto v = reinterpret_cast<duckdb::Vector *>(vector);
99 auto &validity = duckdb::FlatVector::Validity(vector&: *v);
100 validity.EnsureWritable();
101}
102
103void duckdb_vector_assign_string_element(duckdb_vector vector, idx_t index, const char *str) {
104 duckdb_vector_assign_string_element_len(vector, index, str, str_len: strlen(s: str));
105}
106
107void duckdb_vector_assign_string_element_len(duckdb_vector vector, idx_t index, const char *str, idx_t str_len) {
108 if (!vector) {
109 return;
110 }
111 auto v = reinterpret_cast<duckdb::Vector *>(vector);
112 auto data = duckdb::FlatVector::GetData<duckdb::string_t>(vector&: *v);
113 data[index] = duckdb::StringVector::AddString(vector&: *v, data: str, len: str_len);
114}
115
116duckdb_vector duckdb_list_vector_get_child(duckdb_vector vector) {
117 if (!vector) {
118 return nullptr;
119 }
120 auto v = reinterpret_cast<duckdb::Vector *>(vector);
121 return reinterpret_cast<duckdb_vector>(&duckdb::ListVector::GetEntry(vector&: *v));
122}
123
124idx_t duckdb_list_vector_get_size(duckdb_vector vector) {
125 if (!vector) {
126 return 0;
127 }
128 auto v = reinterpret_cast<duckdb::Vector *>(vector);
129 return duckdb::ListVector::GetListSize(vector: *v);
130}
131
132duckdb_state duckdb_list_vector_set_size(duckdb_vector vector, idx_t size) {
133 if (!vector) {
134 return duckdb_state::DuckDBError;
135 }
136 auto v = reinterpret_cast<duckdb::Vector *>(vector);
137 duckdb::ListVector::SetListSize(vec&: *v, size);
138 return duckdb_state::DuckDBSuccess;
139}
140
141duckdb_state duckdb_list_vector_reserve(duckdb_vector vector, idx_t required_capacity) {
142 if (!vector) {
143 return duckdb_state::DuckDBError;
144 }
145 auto v = reinterpret_cast<duckdb::Vector *>(vector);
146 duckdb::ListVector::Reserve(vec&: *v, required_capacity);
147 return duckdb_state::DuckDBSuccess;
148}
149
150duckdb_vector duckdb_struct_vector_get_child(duckdb_vector vector, idx_t index) {
151 if (!vector) {
152 return nullptr;
153 }
154 auto v = reinterpret_cast<duckdb::Vector *>(vector);
155 return reinterpret_cast<duckdb_vector>(duckdb::StructVector::GetEntries(vector&: *v)[index].get());
156}
157
158bool duckdb_validity_row_is_valid(uint64_t *validity, idx_t row) {
159 if (!validity) {
160 return true;
161 }
162 idx_t entry_idx = row / 64;
163 idx_t idx_in_entry = row % 64;
164 return validity[entry_idx] & ((idx_t)1 << idx_in_entry);
165}
166
167void duckdb_validity_set_row_validity(uint64_t *validity, idx_t row, bool valid) {
168 if (valid) {
169 duckdb_validity_set_row_valid(validity, row);
170 } else {
171 duckdb_validity_set_row_invalid(validity, row);
172 }
173}
174
175void duckdb_validity_set_row_invalid(uint64_t *validity, idx_t row) {
176 if (!validity) {
177 return;
178 }
179 idx_t entry_idx = row / 64;
180 idx_t idx_in_entry = row % 64;
181 validity[entry_idx] &= ~((uint64_t)1 << idx_in_entry);
182}
183
184void duckdb_validity_set_row_valid(uint64_t *validity, idx_t row) {
185 if (!validity) {
186 return;
187 }
188 idx_t entry_idx = row / 64;
189 idx_t idx_in_entry = row % 64;
190 validity[entry_idx] |= (uint64_t)1 << idx_in_entry;
191}
192