1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/common/field_writer.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/common/serializer.hpp"
12#include "duckdb/common/set.hpp"
13#include "duckdb/common/serializer/buffered_serializer.hpp"
14#include <type_traits>
15
16namespace duckdb {
17class BufferedSerializer;
18
19struct IndexWriteOperation {
20 template <class SRC, class DST>
21 static DST Operation(SRC input) {
22 return input.index;
23 }
24};
25
26class FieldWriter {
27public:
28 DUCKDB_API explicit FieldWriter(Serializer &serializer);
29 DUCKDB_API ~FieldWriter();
30
31public:
32 template <class T>
33 void WriteField(const T &element) {
34 static_assert(std::is_trivially_destructible<T>(), "WriteField object must be trivially destructible");
35
36 AddField();
37 WriteData(buffer: const_data_ptr_cast(&element), write_size: sizeof(T));
38 }
39
40 //! Write a string with a length prefix
41 void WriteString(const string &val) {
42 WriteStringLen(val: const_data_ptr_cast(src: val.c_str()), len: val.size());
43 }
44 void WriteStringLen(const_data_ptr_t val, idx_t len) {
45 AddField();
46 Write<uint32_t>(element: (uint32_t)len);
47 if (len > 0) {
48 WriteData(buffer: val, write_size: len);
49 }
50 }
51 void WriteBlob(const_data_ptr_t val, idx_t len) {
52 AddField();
53 if (len > 0) {
54 WriteData(buffer: val, write_size: len);
55 }
56 }
57
58 template <class T, class CONTAINER_TYPE = vector<T>>
59 void WriteList(const CONTAINER_TYPE &elements) {
60 AddField();
61 Write<uint32_t>(elements.size());
62 for (auto &element : elements) {
63 Write<T>(element);
64 }
65 }
66
67 template <class T, class SRC, class OP, class CONTAINER_TYPE = vector<SRC>>
68 void WriteGenericList(const CONTAINER_TYPE &elements) {
69 AddField();
70 Write<uint32_t>(elements.size());
71 for (auto &element : elements) {
72 Write<T>(OP::template Operation<SRC, T>(element));
73 }
74 }
75
76 template <class T>
77 void WriteIndexList(const vector<T> &elements) {
78 WriteGenericList<idx_t, T, IndexWriteOperation>(elements);
79 }
80
81 // vector<bool> yay
82 template <class T, class CONTAINER_TYPE = vector<T>>
83 void WriteListNoReference(const CONTAINER_TYPE &elements) {
84 AddField();
85 Write<uint32_t>(elements.size());
86 for (auto element : elements) {
87 Write<T>(element);
88 }
89 }
90
91 template <class T>
92 void WriteSerializable(const T &element) {
93 AddField();
94 element.Serialize(*buffer);
95 }
96
97 template <class T>
98 void WriteSerializableList(const vector<unique_ptr<T>> &elements) {
99 AddField();
100 Write<uint32_t>(elements.size());
101 for (idx_t i = 0; i < elements.size(); i++) {
102 elements[i]->Serialize(*buffer);
103 }
104 }
105
106 template <class T>
107 void WriteRegularSerializableList(const vector<T> &elements) {
108 AddField();
109 Write<uint32_t>(elements.size());
110 for (idx_t i = 0; i < elements.size(); i++) {
111 elements[i].Serialize(*buffer);
112 }
113 }
114
115 template <class T>
116 void WriteOptional(const unique_ptr<T> &element) {
117 AddField();
118 Write<bool>(element ? true : false);
119 if (element) {
120 element->Serialize(*buffer);
121 }
122 }
123
124 // Called after all fields have been written. Should always be called.
125 DUCKDB_API void Finalize();
126
127 Serializer &GetSerializer() {
128 return *buffer;
129 }
130
131 void AddField() {
132 field_count++;
133 }
134
135private:
136 template <class T>
137 void Write(const T &element) {
138 WriteData(buffer: const_data_ptr_cast(&element), write_size: sizeof(T));
139 }
140
141 DUCKDB_API void WriteData(const_data_ptr_t buffer, idx_t write_size);
142
143private:
144 Serializer &serializer;
145 unique_ptr<BufferedSerializer> buffer;
146 idx_t field_count;
147 bool finalized;
148};
149
150template <>
151DUCKDB_API void FieldWriter::Write(const string &val);
152
153class FieldDeserializer : public Deserializer {
154public:
155 explicit FieldDeserializer(Deserializer &root);
156
157public:
158 void ReadData(data_ptr_t buffer, idx_t read_size) override;
159
160 void SetRemainingData(idx_t remaining_data);
161 idx_t RemainingData();
162 Deserializer &GetRoot() {
163 return root;
164 }
165
166 ClientContext &GetContext() override {
167 return root.GetContext();
168 }
169
170 optional_ptr<Catalog> GetCatalog() override {
171 return root.GetCatalog();
172 }
173
174private:
175 Deserializer &root;
176 idx_t remaining_data;
177};
178
179struct IndexReadOperation {
180 template <class SRC, class DST>
181 static DST Operation(SRC input) {
182 return DST(input);
183 }
184};
185
186class FieldReader {
187public:
188 DUCKDB_API explicit FieldReader(Deserializer &source);
189 DUCKDB_API ~FieldReader();
190
191public:
192 template <class T>
193 T ReadRequired() {
194 if (field_count >= max_field_count) {
195 // field is not there, throw an exception
196 throw SerializationException("Attempting to read a required field, but field is missing");
197 }
198 // field is there, read the actual value
199 AddField();
200 return source.Read<T>();
201 }
202
203 template <class T>
204 T ReadField(T default_value) {
205 if (field_count >= max_field_count) {
206 // field is not there, read the default value
207 return default_value;
208 }
209 // field is there, read the actual value
210 AddField();
211 return source.Read<T>();
212 }
213
214 template <class T, class CONTAINER_TYPE = vector<T>>
215 bool ReadList(CONTAINER_TYPE &result) {
216 if (field_count >= max_field_count) {
217 // field is not there, return false and leave the result empty
218 return false;
219 }
220 AddField();
221 auto result_count = source.Read<uint32_t>();
222 result.reserve(result_count);
223 for (idx_t i = 0; i < result_count; i++) {
224 result.push_back(source.Read<T>());
225 }
226 return true;
227 }
228
229 template <class T, class CONTAINER_TYPE = vector<T>>
230 CONTAINER_TYPE ReadRequiredList() {
231 if (field_count >= max_field_count) {
232 // field is not there, throw an exception
233 throw SerializationException("Attempting to read a required field, but field is missing");
234 }
235 AddField();
236 auto result_count = source.Read<uint32_t>();
237 CONTAINER_TYPE result;
238 result.reserve(result_count);
239 for (idx_t i = 0; i < result_count; i++) {
240 result.push_back(source.Read<T>());
241 }
242 return result;
243 }
244
245 template <class T, class SRC, class OP>
246 vector<T> ReadRequiredGenericList() {
247 if (field_count >= max_field_count) {
248 // field is not there, throw an exception
249 throw SerializationException("Attempting to read a required field, but field is missing");
250 }
251 AddField();
252 auto result_count = source.Read<uint32_t>();
253 vector<T> result;
254 result.reserve(result_count);
255 for (idx_t i = 0; i < result_count; i++) {
256 result.push_back(OP::template Operation<SRC, T>(source.Read<SRC>()));
257 }
258 return result;
259 }
260
261 template <class T>
262 vector<T> ReadRequiredIndexList() {
263 return ReadRequiredGenericList<T, idx_t, IndexReadOperation>();
264 }
265
266 template <class T, class CONTAINER_TYPE = set<T>>
267 CONTAINER_TYPE ReadRequiredSet() {
268 if (field_count >= max_field_count) {
269 // field is not there, throw an exception
270 throw SerializationException("Attempting to read a required field, but field is missing");
271 }
272 AddField();
273 auto result_count = source.Read<uint32_t>();
274 CONTAINER_TYPE result;
275 for (idx_t i = 0; i < result_count; i++) {
276 result.insert(source.Read<T>());
277 }
278 return result;
279 }
280
281 template <class T, typename... ARGS>
282 unique_ptr<T> ReadOptional(unique_ptr<T> default_value, ARGS &&... args) {
283 if (field_count >= max_field_count) {
284 // field is not there, read the default value
285 return default_value;
286 }
287 // field is there, read the actual value
288 AddField();
289 return source.template ReadOptional<T>(std::forward<ARGS>(args)...);
290 }
291
292 template <class T, class RETURN_TYPE = unique_ptr<T>>
293 RETURN_TYPE ReadSerializable(RETURN_TYPE default_value) {
294 if (field_count >= max_field_count) {
295 // field is not there, read the default value
296 return default_value;
297 }
298 // field is there, read the actual value
299 AddField();
300 return T::Deserialize(source);
301 }
302
303 template <class T, class RETURN_TYPE = unique_ptr<T>, typename... ARGS>
304 RETURN_TYPE ReadSerializable(RETURN_TYPE default_value, ARGS &&... args) {
305 if (field_count >= max_field_count) {
306 // field is not there, read the default value
307 return default_value;
308 }
309 // field is there, read the actual value
310 AddField();
311 return T::Deserialize(source, std::forward<ARGS>(args)...);
312 }
313
314 template <class T, class RETURN_TYPE = unique_ptr<T>>
315 RETURN_TYPE ReadRequiredSerializable() {
316 if (field_count >= max_field_count) {
317 // field is not there, throw an exception
318 throw SerializationException("Attempting to read mandatory field, but field is missing");
319 }
320 // field is there, read the actual value
321 AddField();
322 return T::Deserialize(source);
323 }
324
325 template <class T, class RETURN_TYPE = unique_ptr<T>, typename... ARGS>
326 RETURN_TYPE ReadRequiredSerializable(ARGS &&... args) {
327 if (field_count >= max_field_count) {
328 // field is not there, throw an exception
329 throw SerializationException("Attempting to read mandatory field, but field is missing");
330 }
331 // field is there, read the actual value
332 AddField();
333 return T::Deserialize(source, std::forward<ARGS>(args)...);
334 }
335
336 template <class T, class RETURN_TYPE = unique_ptr<T>, typename... ARGS>
337 vector<RETURN_TYPE> ReadRequiredSerializableList(ARGS &&... args) {
338 if (field_count >= max_field_count) {
339 // field is not there, throw an exception
340 throw SerializationException("Attempting to read mandatory field, but field is missing");
341 }
342 // field is there, read the actual value
343 AddField();
344 auto result_count = source.Read<uint32_t>();
345
346 vector<RETURN_TYPE> result;
347 for (idx_t i = 0; i < result_count; i++) {
348 result.push_back(T::Deserialize(source, std::forward<ARGS>(args)...));
349 }
350 return result;
351 }
352
353 void ReadBlob(data_ptr_t result, idx_t read_size) {
354 if (field_count >= max_field_count) {
355 // field is not there, throw an exception
356 throw SerializationException("Attempting to read a required field, but field is missing");
357 }
358 // field is there, read the actual value
359 AddField();
360 source.ReadData(buffer: result, read_size);
361 }
362
363 //! Called after all fields have been read. Should always be called.
364 DUCKDB_API void Finalize();
365
366 Deserializer &GetSource() {
367 return source;
368 }
369
370private:
371 void AddField() {
372 field_count++;
373 }
374
375private:
376 FieldDeserializer source;
377 idx_t field_count;
378 idx_t max_field_count;
379 idx_t total_size;
380 bool finalized;
381};
382
383} // namespace duckdb
384