duckdb 0.7.2-dev3353.0 → 0.7.2-dev3402.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/package.json +1 -1
  2. package/src/duckdb/extension/json/buffered_json_reader.cpp +2 -3
  3. package/src/duckdb/extension/json/include/json_functions.hpp +5 -1
  4. package/src/duckdb/extension/json/include/json_scan.hpp +1 -0
  5. package/src/duckdb/extension/json/include/json_transform.hpp +2 -2
  6. package/src/duckdb/extension/json/json-extension.cpp +7 -3
  7. package/src/duckdb/extension/json/json_functions/copy_json.cpp +16 -5
  8. package/src/duckdb/extension/json/json_functions/json_create.cpp +220 -93
  9. package/src/duckdb/extension/json/json_functions/json_merge_patch.cpp +2 -2
  10. package/src/duckdb/extension/json/json_functions/json_transform.cpp +283 -117
  11. package/src/duckdb/extension/json/json_functions/read_json.cpp +8 -6
  12. package/src/duckdb/extension/json/json_functions.cpp +17 -15
  13. package/src/duckdb/extension/json/json_scan.cpp +8 -4
  14. package/src/duckdb/extension/parquet/column_reader.cpp +6 -2
  15. package/src/duckdb/extension/parquet/include/parquet_reader.hpp +1 -2
  16. package/src/duckdb/extension/parquet/include/parquet_writer.hpp +2 -2
  17. package/src/duckdb/extension/parquet/include/string_column_reader.hpp +1 -0
  18. package/src/duckdb/extension/parquet/include/thrift_tools.hpp +3 -5
  19. package/src/duckdb/extension/parquet/parquet-extension.cpp +2 -4
  20. package/src/duckdb/extension/parquet/parquet_reader.cpp +11 -22
  21. package/src/duckdb/extension/parquet/parquet_statistics.cpp +5 -0
  22. package/src/duckdb/extension/parquet/parquet_writer.cpp +4 -4
  23. package/src/duckdb/src/common/file_system.cpp +13 -20
  24. package/src/duckdb/src/common/serializer/buffered_file_writer.cpp +2 -2
  25. package/src/duckdb/src/execution/index/art/art.cpp +3 -1
  26. package/src/duckdb/src/execution/operator/join/physical_index_join.cpp +0 -1
  27. package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +2 -2
  28. package/src/duckdb/src/execution/operator/persistent/parallel_csv_reader.cpp +1 -1
  29. package/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp +1 -2
  30. package/src/duckdb/src/execution/operator/persistent/physical_export.cpp +4 -5
  31. package/src/duckdb/src/execution/physical_plan/plan_copy_to_file.cpp +1 -1
  32. package/src/duckdb/src/function/cast/cast_function_set.cpp +89 -25
  33. package/src/duckdb/src/function/pragma/pragma_queries.cpp +20 -15
  34. package/src/duckdb/src/function/table/copy_csv.cpp +4 -5
  35. package/src/duckdb/src/function/table/read_csv.cpp +6 -5
  36. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  37. package/src/duckdb/src/include/duckdb/common/file_opener.hpp +0 -1
  38. package/src/duckdb/src/include/duckdb/common/file_system.hpp +7 -6
  39. package/src/duckdb/src/include/duckdb/common/opener_file_system.hpp +118 -0
  40. package/src/duckdb/src/include/duckdb/common/serializer/buffered_file_writer.hpp +1 -2
  41. package/src/duckdb/src/include/duckdb/common/types/type_map.hpp +19 -1
  42. package/src/duckdb/src/include/duckdb/execution/operator/persistent/base_csv_reader.hpp +3 -2
  43. package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_line_info.hpp +1 -0
  44. package/src/duckdb/src/include/duckdb/main/client_data.hpp +4 -0
  45. package/src/duckdb/src/include/duckdb/main/extension_helper.hpp +5 -5
  46. package/src/duckdb/src/main/client_context.cpp +0 -4
  47. package/src/duckdb/src/main/client_data.cpp +19 -0
  48. package/src/duckdb/src/main/database.cpp +4 -1
  49. package/src/duckdb/src/main/extension/extension_install.cpp +5 -6
  50. package/src/duckdb/src/main/extension/extension_load.cpp +11 -16
  51. package/src/duckdb/src/main/settings/settings.cpp +2 -3
@@ -1,17 +1,21 @@
1
+ #include "duckdb/function/cast/cast_function_set.hpp"
2
+ #include "duckdb/function/cast/default_casts.hpp"
1
3
  #include "duckdb/planner/expression/bound_parameter_expression.hpp"
2
4
  #include "json_common.hpp"
3
5
  #include "json_functions.hpp"
4
6
 
5
7
  namespace duckdb {
6
8
 
9
+ using StructNames = unordered_map<string, unique_ptr<Vector>>;
10
+
7
11
  struct JSONCreateFunctionData : public FunctionData {
8
12
  public:
9
- explicit JSONCreateFunctionData(unordered_map<string, duckdb::unique_ptr<Vector>> const_struct_names)
13
+ explicit JSONCreateFunctionData(unordered_map<string, unique_ptr<Vector>> const_struct_names)
10
14
  : const_struct_names(std::move(const_struct_names)) {
11
15
  }
12
- duckdb::unique_ptr<FunctionData> Copy() const override {
16
+ unique_ptr<FunctionData> Copy() const override {
13
17
  // Have to do this because we can't implicitly copy Vector
14
- unordered_map<string, duckdb::unique_ptr<Vector>> map_copy;
18
+ unordered_map<string, unique_ptr<Vector>> map_copy;
15
19
  for (const auto &kv : const_struct_names) {
16
20
  // The vectors are const vectors of the key value
17
21
  map_copy[kv.first] = make_uniq<Vector>(Value(kv.first));
@@ -24,11 +28,10 @@ public:
24
28
 
25
29
  public:
26
30
  // Const struct name vectors live here so they don't have to be re-initialized for every DataChunk
27
- unordered_map<string, duckdb::unique_ptr<Vector>> const_struct_names;
31
+ StructNames const_struct_names;
28
32
  };
29
33
 
30
- static LogicalType GetJSONType(unordered_map<string, duckdb::unique_ptr<Vector>> &const_struct_names,
31
- const LogicalType &type) {
34
+ static LogicalType GetJSONType(StructNames &const_struct_names, const LogicalType &type) {
32
35
  if (JSONCommon::LogicalTypeIsJSON(type)) {
33
36
  return type;
34
37
  }
@@ -86,9 +89,9 @@ static LogicalType GetJSONType(unordered_map<string, duckdb::unique_ptr<Vector>>
86
89
  }
87
90
  }
88
91
 
89
- static duckdb::unique_ptr<FunctionData>
90
- JSONCreateBindParams(ScalarFunction &bound_function, vector<duckdb::unique_ptr<Expression>> &arguments, bool object) {
91
- unordered_map<string, duckdb::unique_ptr<Vector>> const_struct_names;
92
+ static unique_ptr<FunctionData> JSONCreateBindParams(ScalarFunction &bound_function,
93
+ vector<unique_ptr<Expression>> &arguments, bool object) {
94
+ unordered_map<string, unique_ptr<Vector>> const_struct_names;
92
95
  for (idx_t i = 0; i < arguments.size(); i++) {
93
96
  auto &type = arguments[i]->return_type;
94
97
  if (arguments[i]->HasParameter()) {
@@ -107,29 +110,29 @@ JSONCreateBindParams(ScalarFunction &bound_function, vector<duckdb::unique_ptr<E
107
110
  return make_uniq<JSONCreateFunctionData>(std::move(const_struct_names));
108
111
  }
109
112
 
110
- static duckdb::unique_ptr<FunctionData> JSONObjectBind(ClientContext &context, ScalarFunction &bound_function,
111
- vector<duckdb::unique_ptr<Expression>> &arguments) {
113
+ static unique_ptr<FunctionData> JSONObjectBind(ClientContext &context, ScalarFunction &bound_function,
114
+ vector<unique_ptr<Expression>> &arguments) {
112
115
  if (arguments.size() % 2 != 0) {
113
116
  throw InvalidInputException("json_object() requires an even number of arguments");
114
117
  }
115
118
  return JSONCreateBindParams(bound_function, arguments, true);
116
119
  }
117
120
 
118
- static duckdb::unique_ptr<FunctionData> JSONArrayBind(ClientContext &context, ScalarFunction &bound_function,
119
- vector<duckdb::unique_ptr<Expression>> &arguments) {
121
+ static unique_ptr<FunctionData> JSONArrayBind(ClientContext &context, ScalarFunction &bound_function,
122
+ vector<unique_ptr<Expression>> &arguments) {
120
123
  return JSONCreateBindParams(bound_function, arguments, false);
121
124
  }
122
125
 
123
- static duckdb::unique_ptr<FunctionData> ToJSONBind(ClientContext &context, ScalarFunction &bound_function,
124
- vector<duckdb::unique_ptr<Expression>> &arguments) {
126
+ static unique_ptr<FunctionData> ToJSONBind(ClientContext &context, ScalarFunction &bound_function,
127
+ vector<unique_ptr<Expression>> &arguments) {
125
128
  if (arguments.size() != 1) {
126
129
  throw InvalidInputException("to_json() takes exactly one argument");
127
130
  }
128
131
  return JSONCreateBindParams(bound_function, arguments, false);
129
132
  }
130
133
 
131
- static duckdb::unique_ptr<FunctionData> ArrayToJSONBind(ClientContext &context, ScalarFunction &bound_function,
132
- vector<duckdb::unique_ptr<Expression>> &arguments) {
134
+ static unique_ptr<FunctionData> ArrayToJSONBind(ClientContext &context, ScalarFunction &bound_function,
135
+ vector<unique_ptr<Expression>> &arguments) {
133
136
  if (arguments.size() != 1) {
134
137
  throw InvalidInputException("array_to_json() takes exactly one argument");
135
138
  }
@@ -143,8 +146,8 @@ static duckdb::unique_ptr<FunctionData> ArrayToJSONBind(ClientContext &context,
143
146
  return JSONCreateBindParams(bound_function, arguments, false);
144
147
  }
145
148
 
146
- static duckdb::unique_ptr<FunctionData> RowToJSONBind(ClientContext &context, ScalarFunction &bound_function,
147
- vector<duckdb::unique_ptr<Expression>> &arguments) {
149
+ static unique_ptr<FunctionData> RowToJSONBind(ClientContext &context, ScalarFunction &bound_function,
150
+ vector<unique_ptr<Expression>> &arguments) {
148
151
  if (arguments.size() != 1) {
149
152
  throw InvalidInputException("row_to_json() takes exactly one argument");
150
153
  }
@@ -158,35 +161,55 @@ static duckdb::unique_ptr<FunctionData> RowToJSONBind(ClientContext &context, Sc
158
161
  return JSONCreateBindParams(bound_function, arguments, false);
159
162
  }
160
163
 
161
- template <class T>
162
- static inline yyjson_mut_val *CreateJSONValue(yyjson_mut_doc *doc, const T &value) {
163
- throw NotImplementedException("Unsupported type for CreateJSONValue");
164
- }
164
+ template <class INPUT_TYPE, class RESULT_TYPE>
165
+ struct CreateJSONValue {
166
+ static inline RESULT_TYPE Operation(const INPUT_TYPE &input) {
167
+ throw NotImplementedException("Unsupported type for CreateJSONValue");
168
+ }
169
+ };
165
170
 
166
- template <>
167
- inline yyjson_mut_val *CreateJSONValue(yyjson_mut_doc *doc, const bool &value) {
168
- return yyjson_mut_bool(doc, value);
169
- }
171
+ template <class INPUT_TYPE>
172
+ struct CreateJSONValue<INPUT_TYPE, bool> {
173
+ static inline yyjson_mut_val *Operation(yyjson_mut_doc *doc, const INPUT_TYPE &input) {
174
+ return yyjson_mut_bool(doc, input);
175
+ }
176
+ };
170
177
 
171
- template <>
172
- inline yyjson_mut_val *CreateJSONValue(yyjson_mut_doc *doc, const uint64_t &value) {
173
- return yyjson_mut_uint(doc, value);
174
- }
178
+ template <class INPUT_TYPE>
179
+ struct CreateJSONValue<INPUT_TYPE, uint64_t> {
180
+ static inline yyjson_mut_val *Operation(yyjson_mut_doc *doc, const INPUT_TYPE &input) {
181
+ return yyjson_mut_uint(doc, input);
182
+ }
183
+ };
175
184
 
176
- template <>
177
- inline yyjson_mut_val *CreateJSONValue(yyjson_mut_doc *doc, const int64_t &value) {
178
- return yyjson_mut_sint(doc, value);
179
- }
185
+ template <class INPUT_TYPE>
186
+ struct CreateJSONValue<INPUT_TYPE, int64_t> {
187
+ static inline yyjson_mut_val *Operation(yyjson_mut_doc *doc, const INPUT_TYPE &input) {
188
+ return yyjson_mut_sint(doc, input);
189
+ }
190
+ };
191
+
192
+ template <class INPUT_TYPE>
193
+ struct CreateJSONValue<INPUT_TYPE, double> {
194
+ static inline yyjson_mut_val *Operation(yyjson_mut_doc *doc, const INPUT_TYPE &input) {
195
+ return yyjson_mut_real(doc, input);
196
+ }
197
+ };
180
198
 
181
199
  template <>
182
- inline yyjson_mut_val *CreateJSONValue(yyjson_mut_doc *doc, const double &value) {
183
- return yyjson_mut_real(doc, value);
184
- }
200
+ struct CreateJSONValue<string_t, string_t> {
201
+ static inline yyjson_mut_val *Operation(yyjson_mut_doc *doc, const string_t &input) {
202
+ return yyjson_mut_strncpy(doc, input.GetData(), input.GetSize());
203
+ }
204
+ };
185
205
 
186
206
  template <>
187
- inline yyjson_mut_val *CreateJSONValue(yyjson_mut_doc *doc, const string_t &value) {
188
- return yyjson_mut_strn(doc, value.GetData(), value.GetSize());
189
- }
207
+ struct CreateJSONValue<hugeint_t, string_t> {
208
+ static inline yyjson_mut_val *Operation(yyjson_mut_doc *doc, const hugeint_t &input) {
209
+ const auto input_string = input.ToString();
210
+ return yyjson_mut_strncpy(doc, input_string.c_str(), input_string.length());
211
+ }
212
+ };
190
213
 
191
214
  inline yyjson_mut_val *CreateJSONValueFromJSON(yyjson_mut_doc *doc, const string_t &value) {
192
215
  auto value_doc = JSONCommon::ReadDocument(value, JSONCommon::READ_FLAG, &doc->alc);
@@ -195,8 +218,8 @@ inline yyjson_mut_val *CreateJSONValueFromJSON(yyjson_mut_doc *doc, const string
195
218
  }
196
219
 
197
220
  // Forward declaration so we can recurse for nested types
198
- static void CreateValues(const JSONCreateFunctionData &info, yyjson_mut_doc *doc, yyjson_mut_val *vals[],
199
- Vector &value_v, idx_t count);
221
+ static void CreateValues(const StructNames &names, yyjson_mut_doc *doc, yyjson_mut_val *vals[], Vector &value_v,
222
+ idx_t count);
200
223
 
201
224
  static void AddKeyValuePairs(yyjson_mut_doc *doc, yyjson_mut_val *objs[], Vector &key_v, yyjson_mut_val *vals[],
202
225
  idx_t count) {
@@ -209,14 +232,14 @@ static void AddKeyValuePairs(yyjson_mut_doc *doc, yyjson_mut_val *objs[], Vector
209
232
  if (!key_data.validity.RowIsValid(key_idx)) {
210
233
  continue;
211
234
  }
212
- auto key = CreateJSONValue<string_t>(doc, keys[key_idx]);
235
+ auto key = CreateJSONValue<string_t, string_t>::Operation(doc, keys[key_idx]);
213
236
  yyjson_mut_obj_add(objs[i], key, vals[i]);
214
237
  }
215
238
  }
216
239
 
217
- static void CreateKeyValuePairs(const JSONCreateFunctionData &info, yyjson_mut_doc *doc, yyjson_mut_val *objs[],
240
+ static void CreateKeyValuePairs(const StructNames &names, yyjson_mut_doc *doc, yyjson_mut_val *objs[],
218
241
  yyjson_mut_val *vals[], Vector &key_v, Vector &value_v, idx_t count) {
219
- CreateValues(info, doc, vals, value_v, count);
242
+ CreateValues(names, doc, vals, value_v, count);
220
243
  AddKeyValuePairs(doc, objs, key_v, vals, count);
221
244
  }
222
245
 
@@ -226,11 +249,11 @@ static void CreateValuesNull(yyjson_mut_doc *doc, yyjson_mut_val *vals[], idx_t
226
249
  }
227
250
  }
228
251
 
229
- template <class T>
252
+ template <class INPUT_TYPE, class TARGET_TYPE>
230
253
  static void TemplatedCreateValues(yyjson_mut_doc *doc, yyjson_mut_val *vals[], Vector &value_v, idx_t count) {
231
254
  UnifiedVectorFormat value_data;
232
255
  value_v.ToUnifiedFormat(count, value_data);
233
- auto values = (T *)value_data.data;
256
+ auto values = (INPUT_TYPE *)value_data.data;
234
257
 
235
258
  const auto type_is_json = JSONCommon::LogicalTypeIsJSON(value_v.GetType());
236
259
  for (idx_t i = 0; i < count; i++) {
@@ -240,14 +263,14 @@ static void TemplatedCreateValues(yyjson_mut_doc *doc, yyjson_mut_val *vals[], V
240
263
  } else if (type_is_json) {
241
264
  vals[i] = CreateJSONValueFromJSON(doc, (string_t &)values[val_idx]);
242
265
  } else {
243
- vals[i] = CreateJSONValue<T>(doc, values[val_idx]);
266
+ vals[i] = CreateJSONValue<INPUT_TYPE, TARGET_TYPE>::Operation(doc, values[val_idx]);
244
267
  }
245
268
  D_ASSERT(vals[i] != nullptr);
246
269
  }
247
270
  }
248
271
 
249
- static void CreateValuesStruct(const JSONCreateFunctionData &info, yyjson_mut_doc *doc, yyjson_mut_val *vals[],
250
- Vector &value_v, idx_t count) {
272
+ static void CreateValuesStruct(const StructNames &names, yyjson_mut_doc *doc, yyjson_mut_val *vals[], Vector &value_v,
273
+ idx_t count) {
251
274
  // Structs become values, therefore we initialize vals to JSON values
252
275
  for (idx_t i = 0; i < count; i++) {
253
276
  vals[i] = yyjson_mut_obj(doc);
@@ -258,9 +281,9 @@ static void CreateValuesStruct(const JSONCreateFunctionData &info, yyjson_mut_do
258
281
  // Add the key/value pairs to the values
259
282
  auto &entries = StructVector::GetEntries(value_v);
260
283
  for (idx_t entry_i = 0; entry_i < entries.size(); entry_i++) {
261
- auto &struct_key_v = *info.const_struct_names.at(StructType::GetChildName(value_v.GetType(), entry_i));
284
+ auto &struct_key_v = *names.at(StructType::GetChildName(value_v.GetType(), entry_i));
262
285
  auto &struct_val_v = *entries[entry_i];
263
- CreateKeyValuePairs(info, doc, vals, nested_vals, struct_key_v, struct_val_v, count);
286
+ CreateKeyValuePairs(names, doc, vals, nested_vals, struct_key_v, struct_val_v, count);
264
287
  }
265
288
  // Whole struct can be NULL
266
289
  UnifiedVectorFormat struct_data;
@@ -273,18 +296,18 @@ static void CreateValuesStruct(const JSONCreateFunctionData &info, yyjson_mut_do
273
296
  }
274
297
  }
275
298
 
276
- static void CreateValuesMap(const JSONCreateFunctionData &info, yyjson_mut_doc *doc, yyjson_mut_val *vals[],
277
- Vector &value_v, idx_t count) {
299
+ static void CreateValuesMap(const StructNames &names, yyjson_mut_doc *doc, yyjson_mut_val *vals[], Vector &value_v,
300
+ idx_t count) {
278
301
  // Create nested keys
279
302
  auto &map_key_v = MapVector::GetKeys(value_v);
280
303
  auto map_key_count = ListVector::GetListSize(value_v);
281
304
  auto nested_keys = (yyjson_mut_val **)doc->alc.malloc(doc->alc.ctx, sizeof(yyjson_mut_val *) * map_key_count);
282
- TemplatedCreateValues<string_t>(doc, nested_keys, map_key_v, map_key_count);
305
+ TemplatedCreateValues<string_t, string_t>(doc, nested_keys, map_key_v, map_key_count);
283
306
  // Create nested values
284
307
  auto &map_val_v = MapVector::GetValues(value_v);
285
308
  auto map_val_count = ListVector::GetListSize(value_v);
286
309
  auto nested_vals = (yyjson_mut_val **)doc->alc.malloc(doc->alc.ctx, sizeof(yyjson_mut_val *) * map_val_count);
287
- CreateValues(info, doc, nested_vals, map_val_v, map_val_count);
310
+ CreateValues(names, doc, nested_vals, map_val_v, map_val_count);
288
311
  // Add the key/value pairs to the values
289
312
  UnifiedVectorFormat map_data;
290
313
  value_v.ToUnifiedFormat(count, map_data);
@@ -307,8 +330,8 @@ static void CreateValuesMap(const JSONCreateFunctionData &info, yyjson_mut_doc *
307
330
  }
308
331
  }
309
332
 
310
- static void CreateValuesUnion(const JSONCreateFunctionData &info, yyjson_mut_doc *doc, yyjson_mut_val *vals[],
311
- Vector &value_v, idx_t count) {
333
+ static void CreateValuesUnion(const StructNames &names, yyjson_mut_doc *doc, yyjson_mut_val *vals[], Vector &value_v,
334
+ idx_t count) {
312
335
  // Structs become values, therefore we initialize vals to JSON values
313
336
  for (idx_t i = 0; i < count; i++) {
314
337
  vals[i] = yyjson_mut_obj(doc);
@@ -324,12 +347,12 @@ static void CreateValuesUnion(const JSONCreateFunctionData &info, yyjson_mut_doc
324
347
  // Add the key/value pairs to the values
325
348
  for (idx_t member_idx = 0; member_idx < UnionType::GetMemberCount(value_v.GetType()); member_idx++) {
326
349
  auto &member_val_v = UnionVector::GetMember(value_v, member_idx);
327
- auto &member_key_v = *info.const_struct_names.at(UnionType::GetMemberName(value_v.GetType(), member_idx));
350
+ auto &member_key_v = *names.at(UnionType::GetMemberName(value_v.GetType(), member_idx));
328
351
 
329
352
  // This implementation is not optimal since we convert the entire member vector,
330
353
  // and then skip the rows not matching the tag afterwards.
331
354
 
332
- CreateValues(info, doc, nested_vals, member_val_v, count);
355
+ CreateValues(names, doc, nested_vals, member_val_v, count);
333
356
 
334
357
  // This is a inlined copy of AddKeyValuePairs but we also skip null tags
335
358
  // and the rows where the member is not matching the tag
@@ -350,20 +373,20 @@ static void CreateValuesUnion(const JSONCreateFunctionData &info, yyjson_mut_doc
350
373
  if (!key_data.validity.RowIsValid(key_idx)) {
351
374
  continue;
352
375
  }
353
- auto key = CreateJSONValue<string_t>(doc, keys[key_idx]);
376
+ auto key = CreateJSONValue<string_t, string_t>::Operation(doc, keys[key_idx]);
354
377
  yyjson_mut_obj_add(vals[i], key, nested_vals[i]);
355
378
  }
356
379
  }
357
380
  }
358
381
 
359
- static void CreateValuesList(const JSONCreateFunctionData &info, yyjson_mut_doc *doc, yyjson_mut_val *vals[],
360
- Vector &value_v, idx_t count) {
382
+ static void CreateValuesList(const StructNames &names, yyjson_mut_doc *doc, yyjson_mut_val *vals[], Vector &value_v,
383
+ idx_t count) {
361
384
  // Initialize array for the nested values
362
385
  auto &child_v = ListVector::GetEntry(value_v);
363
386
  auto child_count = ListVector::GetListSize(value_v);
364
387
  auto nested_vals = (yyjson_mut_val **)doc->alc.malloc(doc->alc.ctx, sizeof(yyjson_mut_val *) * child_count);
365
388
  // Fill nested_vals with list values
366
- CreateValues(info, doc, nested_vals, child_v, child_count);
389
+ CreateValues(names, doc, nested_vals, child_v, child_count);
367
390
  // Now we add the values to the appropriate JSON arrays
368
391
  UnifiedVectorFormat list_data;
369
392
  value_v.ToUnifiedFormat(count, list_data);
@@ -382,39 +405,88 @@ static void CreateValuesList(const JSONCreateFunctionData &info, yyjson_mut_doc
382
405
  }
383
406
  }
384
407
 
385
- static void CreateValues(const JSONCreateFunctionData &info, yyjson_mut_doc *doc, yyjson_mut_val *vals[],
386
- Vector &value_v, idx_t count) {
408
+ static void CreateValues(const StructNames &names, yyjson_mut_doc *doc, yyjson_mut_val *vals[], Vector &value_v,
409
+ idx_t count) {
387
410
  switch (value_v.GetType().id()) {
388
411
  case LogicalTypeId::SQLNULL:
389
412
  CreateValuesNull(doc, vals, count);
390
413
  break;
391
414
  case LogicalTypeId::BOOLEAN:
392
- TemplatedCreateValues<bool>(doc, vals, value_v, count);
415
+ TemplatedCreateValues<bool, bool>(doc, vals, value_v, count);
416
+ break;
417
+ case LogicalTypeId::TINYINT:
418
+ TemplatedCreateValues<int8_t, int64_t>(doc, vals, value_v, count);
419
+ break;
420
+ case LogicalTypeId::SMALLINT:
421
+ TemplatedCreateValues<int16_t, int64_t>(doc, vals, value_v, count);
422
+ break;
423
+ case LogicalTypeId::INTEGER:
424
+ TemplatedCreateValues<int32_t, int64_t>(doc, vals, value_v, count);
393
425
  break;
394
426
  case LogicalTypeId::BIGINT:
395
- TemplatedCreateValues<int64_t>(doc, vals, value_v, count);
427
+ TemplatedCreateValues<int64_t, int64_t>(doc, vals, value_v, count);
428
+ break;
429
+ case LogicalTypeId::HUGEINT:
430
+ TemplatedCreateValues<hugeint_t, string_t>(doc, vals, value_v, count);
431
+ break;
432
+ case LogicalTypeId::UTINYINT:
433
+ TemplatedCreateValues<uint8_t, uint64_t>(doc, vals, value_v, count);
434
+ break;
435
+ case LogicalTypeId::USMALLINT:
436
+ TemplatedCreateValues<uint16_t, uint64_t>(doc, vals, value_v, count);
437
+ break;
438
+ case LogicalTypeId::UINTEGER:
439
+ TemplatedCreateValues<uint32_t, uint64_t>(doc, vals, value_v, count);
396
440
  break;
397
441
  case LogicalTypeId::UBIGINT:
398
- TemplatedCreateValues<uint64_t>(doc, vals, value_v, count);
442
+ TemplatedCreateValues<uint64_t, uint64_t>(doc, vals, value_v, count);
443
+ break;
444
+ case LogicalTypeId::FLOAT:
445
+ TemplatedCreateValues<float, double>(doc, vals, value_v, count);
399
446
  break;
400
447
  case LogicalTypeId::DOUBLE:
401
- TemplatedCreateValues<double>(doc, vals, value_v, count);
448
+ TemplatedCreateValues<double, double>(doc, vals, value_v, count);
402
449
  break;
450
+ case LogicalTypeId::BIT:
451
+ case LogicalTypeId::BLOB:
403
452
  case LogicalTypeId::VARCHAR:
404
- TemplatedCreateValues<string_t>(doc, vals, value_v, count);
453
+ TemplatedCreateValues<string_t, string_t>(doc, vals, value_v, count);
405
454
  break;
406
455
  case LogicalTypeId::STRUCT:
407
- CreateValuesStruct(info, doc, vals, value_v, count);
456
+ CreateValuesStruct(names, doc, vals, value_v, count);
408
457
  break;
409
458
  case LogicalTypeId::MAP:
410
- CreateValuesMap(info, doc, vals, value_v, count);
459
+ CreateValuesMap(names, doc, vals, value_v, count);
411
460
  break;
412
461
  case LogicalTypeId::LIST:
413
- CreateValuesList(info, doc, vals, value_v, count);
462
+ CreateValuesList(names, doc, vals, value_v, count);
414
463
  break;
415
464
  case LogicalTypeId::UNION:
416
- CreateValuesUnion(info, doc, vals, value_v, count);
465
+ CreateValuesUnion(names, doc, vals, value_v, count);
417
466
  break;
467
+ case LogicalTypeId::AGGREGATE_STATE:
468
+ case LogicalTypeId::ENUM:
469
+ case LogicalTypeId::DATE:
470
+ case LogicalTypeId::INTERVAL:
471
+ case LogicalTypeId::TIME:
472
+ case LogicalTypeId::TIME_TZ:
473
+ case LogicalTypeId::TIMESTAMP:
474
+ case LogicalTypeId::TIMESTAMP_TZ:
475
+ case LogicalTypeId::TIMESTAMP_NS:
476
+ case LogicalTypeId::TIMESTAMP_MS:
477
+ case LogicalTypeId::TIMESTAMP_SEC:
478
+ case LogicalTypeId::UUID: {
479
+ Vector string_vector(LogicalTypeId::VARCHAR, count);
480
+ VectorOperations::DefaultCast(value_v, string_vector, count);
481
+ TemplatedCreateValues<string_t, string_t>(doc, vals, string_vector, count);
482
+ break;
483
+ }
484
+ case LogicalTypeId::DECIMAL: {
485
+ Vector double_vector(LogicalType::DOUBLE, count);
486
+ VectorOperations::DefaultCast(value_v, double_vector, count);
487
+ TemplatedCreateValues<double, double>(doc, vals, double_vector, count);
488
+ break;
489
+ }
418
490
  default:
419
491
  throw InternalException("Unsupported type arrived at JSON create function");
420
492
  }
@@ -429,17 +501,17 @@ static void ObjectFunction(DataChunk &args, ExpressionState &state, Vector &resu
429
501
  // Initialize values
430
502
  const idx_t count = args.size();
431
503
  auto doc = JSONCommon::CreateDocument(alc);
432
- yyjson_mut_val *objs[STANDARD_VECTOR_SIZE];
504
+ auto objs = (yyjson_mut_val **)alc->malloc(alc->ctx, sizeof(yyjson_mut_val *) * count);
433
505
  for (idx_t i = 0; i < count; i++) {
434
506
  objs[i] = yyjson_mut_obj(doc);
435
507
  }
436
508
  // Initialize a re-usable value array
437
- yyjson_mut_val *vals[STANDARD_VECTOR_SIZE];
509
+ auto vals = (yyjson_mut_val **)alc->malloc(alc->ctx, sizeof(yyjson_mut_val *) * count);
438
510
  // Loop through key/value pairs
439
511
  for (idx_t pair_idx = 0; pair_idx < args.data.size() / 2; pair_idx++) {
440
512
  Vector &key_v = args.data[pair_idx * 2];
441
513
  Vector &value_v = args.data[pair_idx * 2 + 1];
442
- CreateKeyValuePairs(info, doc, objs, vals, key_v, value_v, count);
514
+ CreateKeyValuePairs(info.const_struct_names, doc, objs, vals, key_v, value_v, count);
443
515
  }
444
516
  // Write JSON values to string
445
517
  auto objects = FlatVector::GetData<string_t>(result);
@@ -461,15 +533,15 @@ static void ArrayFunction(DataChunk &args, ExpressionState &state, Vector &resul
461
533
  // Initialize arrays
462
534
  const idx_t count = args.size();
463
535
  auto doc = JSONCommon::CreateDocument(alc);
464
- yyjson_mut_val *arrs[STANDARD_VECTOR_SIZE];
536
+ auto arrs = (yyjson_mut_val **)alc->malloc(alc->ctx, sizeof(yyjson_mut_val *) * count);
465
537
  for (idx_t i = 0; i < count; i++) {
466
538
  arrs[i] = yyjson_mut_arr(doc);
467
539
  }
468
540
  // Initialize a re-usable value array
469
- yyjson_mut_val *vals[STANDARD_VECTOR_SIZE];
541
+ auto vals = (yyjson_mut_val **)alc->malloc(alc->ctx, sizeof(yyjson_mut_val *) * count);
470
542
  // Loop through args
471
543
  for (auto &v : args.data) {
472
- CreateValues(info, doc, vals, v, count);
544
+ CreateValues(info.const_struct_names, doc, vals, v, count);
473
545
  for (idx_t i = 0; i < count; i++) {
474
546
  yyjson_mut_arr_append(arrs[i], vals[i]);
475
547
  }
@@ -485,22 +557,18 @@ static void ArrayFunction(DataChunk &args, ExpressionState &state, Vector &resul
485
557
  }
486
558
  }
487
559
 
488
- static void ToJSONFunction(DataChunk &args, ExpressionState &state, Vector &result) {
489
- auto &func_expr = state.expr.Cast<BoundFunctionExpression>();
490
- const auto &info = (JSONCreateFunctionData &)*func_expr.bind_info;
491
- auto &lstate = JSONFunctionLocalState::ResetAndGet(state);
492
- auto alc = lstate.json_allocator.GetYYJSONAllocator();
493
-
560
+ static void ToJSONFunctionInternal(const StructNames &names, Vector &input, const idx_t count, Vector &result,
561
+ yyjson_alc *alc) {
494
562
  // Initialize array for values
495
- const idx_t count = args.size();
496
563
  auto doc = JSONCommon::CreateDocument(alc);
497
- yyjson_mut_val *vals[STANDARD_VECTOR_SIZE];
498
- CreateValues(info, doc, vals, args.data[0], count);
564
+ auto vals = (yyjson_mut_val **)alc->malloc(alc->ctx, sizeof(yyjson_mut_val *) * count);
565
+ CreateValues(names, doc, vals, input, count);
566
+
499
567
  // Write JSON values to string
500
568
  auto objects = FlatVector::GetData<string_t>(result);
501
569
  auto &result_validity = FlatVector::Validity(result);
502
570
  UnifiedVectorFormat input_data;
503
- args.data[0].ToUnifiedFormat(count, input_data);
571
+ input.ToUnifiedFormat(count, input_data);
504
572
  for (idx_t i = 0; i < count; i++) {
505
573
  idx_t idx = input_data.sel->get_index(i);
506
574
  if (input_data.validity.RowIsValid(idx)) {
@@ -510,11 +578,20 @@ static void ToJSONFunction(DataChunk &args, ExpressionState &state, Vector &resu
510
578
  }
511
579
  }
512
580
 
513
- if (args.AllConstant()) {
581
+ if (input.GetVectorType() == VectorType::CONSTANT_VECTOR) {
514
582
  result.SetVectorType(VectorType::CONSTANT_VECTOR);
515
583
  }
516
584
  }
517
585
 
586
+ static void ToJSONFunction(DataChunk &args, ExpressionState &state, Vector &result) {
587
+ auto &func_expr = state.expr.Cast<BoundFunctionExpression>();
588
+ const auto &info = (JSONCreateFunctionData &)*func_expr.bind_info;
589
+ auto &lstate = JSONFunctionLocalState::ResetAndGet(state);
590
+ auto alc = lstate.json_allocator.GetYYJSONAllocator();
591
+
592
+ ToJSONFunctionInternal(info.const_struct_names, args.data[0], args.size(), result, alc);
593
+ }
594
+
518
595
  ScalarFunctionSet JSONFunctions::GetObjectFunction() {
519
596
  ScalarFunction fun("json_object", {}, JSONCommon::JSONType(), ObjectFunction, JSONObjectBind, nullptr, nullptr,
520
597
  JSONFunctionLocalState::Init);
@@ -552,4 +629,54 @@ ScalarFunctionSet JSONFunctions::GetRowToJSONFunction() {
552
629
  return ScalarFunctionSet(fun);
553
630
  }
554
631
 
632
+ struct NestedToJSONCastData : public BoundCastData {
633
+ public:
634
+ NestedToJSONCastData() {
635
+ }
636
+
637
+ unique_ptr<BoundCastData> Copy() const override {
638
+ auto result = make_uniq<NestedToJSONCastData>();
639
+ for (auto &csn : const_struct_names) {
640
+ result->const_struct_names.emplace(csn.first, make_uniq<Vector>(csn.second->GetValue(0)));
641
+ }
642
+ return result;
643
+ }
644
+
645
+ public:
646
+ StructNames const_struct_names;
647
+ };
648
+
649
+ static bool AnyToJSONCast(Vector &source, Vector &result, idx_t count, CastParameters &parameters) {
650
+ auto &lstate = parameters.local_state->Cast<JSONFunctionLocalState>();
651
+ lstate.json_allocator.Reset();
652
+ auto alc = lstate.json_allocator.GetYYJSONAllocator();
653
+ const auto &names = parameters.cast_data->Cast<NestedToJSONCastData>().const_struct_names;
654
+
655
+ ToJSONFunctionInternal(names, source, count, result, alc);
656
+ return true;
657
+ }
658
+
659
+ BoundCastInfo AnyToJSONCastBind(BindCastInput &input, const LogicalType &source, const LogicalType &target) {
660
+ auto cast_data = make_uniq<NestedToJSONCastData>();
661
+ GetJSONType(cast_data->const_struct_names, source);
662
+ return BoundCastInfo(AnyToJSONCast, std::move(cast_data), JSONFunctionLocalState::InitCastLocalState);
663
+ }
664
+
665
+ void JSONFunctions::RegisterJSONCreateCastFunctions(CastFunctionSet &casts) {
666
+ auto json_to_any_cost = casts.ImplicitCastCost(LogicalType::ANY, JSONCommon::JSONType());
667
+ casts.RegisterCastFunction(LogicalType::ANY, JSONCommon::JSONType(), AnyToJSONCastBind, json_to_any_cost);
668
+
669
+ const auto struct_type = LogicalType::STRUCT({{"any", LogicalType::ANY}});
670
+ auto struct_to_json_cost = casts.ImplicitCastCost(struct_type, LogicalType::VARCHAR) - 2;
671
+ casts.RegisterCastFunction(struct_type, JSONCommon::JSONType(), AnyToJSONCastBind, struct_to_json_cost);
672
+
673
+ const auto list_type = LogicalType::LIST(LogicalType::ANY);
674
+ auto list_to_json_cost = casts.ImplicitCastCost(list_type, LogicalType::VARCHAR) - 2;
675
+ casts.RegisterCastFunction(list_type, JSONCommon::JSONType(), AnyToJSONCastBind, list_to_json_cost);
676
+
677
+ const auto map_type = LogicalType::MAP(LogicalType::ANY, LogicalType::ANY);
678
+ auto map_to_json_cost = casts.ImplicitCastCost(map_type, LogicalType::VARCHAR) - 2;
679
+ casts.RegisterCastFunction(map_type, JSONCommon::JSONType(), AnyToJSONCastBind, map_to_json_cost);
680
+ }
681
+
555
682
  } // namespace duckdb
@@ -59,11 +59,11 @@ static void MergePatchFunction(DataChunk &args, ExpressionState &state, Vector &
59
59
  const auto count = args.size();
60
60
 
61
61
  // Read the first json arg
62
- yyjson_mut_val *origs[STANDARD_VECTOR_SIZE];
62
+ auto origs = (yyjson_mut_val **)alc->malloc(alc->ctx, sizeof(yyjson_mut_val *) * count);
63
63
  ReadObjects(doc, args.data[0], origs, count);
64
64
 
65
65
  // Read the next json args one by one and merge them into the first json arg
66
- yyjson_mut_val *patches[STANDARD_VECTOR_SIZE];
66
+ auto patches = (yyjson_mut_val **)alc->malloc(alc->ctx, sizeof(yyjson_mut_val *) * count);
67
67
  for (idx_t arg_idx = 1; arg_idx < args.data.size(); arg_idx++) {
68
68
  ReadObjects(doc, args.data[arg_idx], patches, count);
69
69
  for (idx_t i = 0; i < count; i++) {