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.
- package/package.json +1 -1
- package/src/duckdb/extension/json/buffered_json_reader.cpp +2 -3
- package/src/duckdb/extension/json/include/json_functions.hpp +5 -1
- package/src/duckdb/extension/json/include/json_scan.hpp +1 -0
- package/src/duckdb/extension/json/include/json_transform.hpp +2 -2
- package/src/duckdb/extension/json/json-extension.cpp +7 -3
- package/src/duckdb/extension/json/json_functions/copy_json.cpp +16 -5
- package/src/duckdb/extension/json/json_functions/json_create.cpp +220 -93
- package/src/duckdb/extension/json/json_functions/json_merge_patch.cpp +2 -2
- package/src/duckdb/extension/json/json_functions/json_transform.cpp +283 -117
- package/src/duckdb/extension/json/json_functions/read_json.cpp +8 -6
- package/src/duckdb/extension/json/json_functions.cpp +17 -15
- package/src/duckdb/extension/json/json_scan.cpp +8 -4
- package/src/duckdb/extension/parquet/column_reader.cpp +6 -2
- package/src/duckdb/extension/parquet/include/parquet_reader.hpp +1 -2
- package/src/duckdb/extension/parquet/include/parquet_writer.hpp +2 -2
- package/src/duckdb/extension/parquet/include/string_column_reader.hpp +1 -0
- package/src/duckdb/extension/parquet/include/thrift_tools.hpp +3 -5
- package/src/duckdb/extension/parquet/parquet-extension.cpp +2 -4
- package/src/duckdb/extension/parquet/parquet_reader.cpp +11 -22
- package/src/duckdb/extension/parquet/parquet_statistics.cpp +5 -0
- package/src/duckdb/extension/parquet/parquet_writer.cpp +4 -4
- package/src/duckdb/src/common/file_system.cpp +13 -20
- package/src/duckdb/src/common/serializer/buffered_file_writer.cpp +2 -2
- package/src/duckdb/src/execution/index/art/art.cpp +3 -1
- package/src/duckdb/src/execution/operator/join/physical_index_join.cpp +0 -1
- package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +2 -2
- package/src/duckdb/src/execution/operator/persistent/parallel_csv_reader.cpp +1 -1
- package/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp +1 -2
- package/src/duckdb/src/execution/operator/persistent/physical_export.cpp +4 -5
- package/src/duckdb/src/execution/physical_plan/plan_copy_to_file.cpp +1 -1
- package/src/duckdb/src/function/cast/cast_function_set.cpp +89 -25
- package/src/duckdb/src/function/pragma/pragma_queries.cpp +20 -15
- package/src/duckdb/src/function/table/copy_csv.cpp +4 -5
- package/src/duckdb/src/function/table/read_csv.cpp +6 -5
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/common/file_opener.hpp +0 -1
- package/src/duckdb/src/include/duckdb/common/file_system.hpp +7 -6
- package/src/duckdb/src/include/duckdb/common/opener_file_system.hpp +118 -0
- package/src/duckdb/src/include/duckdb/common/serializer/buffered_file_writer.hpp +1 -2
- package/src/duckdb/src/include/duckdb/common/types/type_map.hpp +19 -1
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/base_csv_reader.hpp +3 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_line_info.hpp +1 -0
- package/src/duckdb/src/include/duckdb/main/client_data.hpp +4 -0
- package/src/duckdb/src/include/duckdb/main/extension_helper.hpp +5 -5
- package/src/duckdb/src/main/client_context.cpp +0 -4
- package/src/duckdb/src/main/client_data.cpp +19 -0
- package/src/duckdb/src/main/database.cpp +4 -1
- package/src/duckdb/src/main/extension/extension_install.cpp +5 -6
- package/src/duckdb/src/main/extension/extension_load.cpp +11 -16
- 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,
|
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
|
-
|
16
|
+
unique_ptr<FunctionData> Copy() const override {
|
13
17
|
// Have to do this because we can't implicitly copy Vector
|
14
|
-
unordered_map<string,
|
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
|
-
|
31
|
+
StructNames const_struct_names;
|
28
32
|
};
|
29
33
|
|
30
|
-
static LogicalType GetJSONType(
|
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
|
90
|
-
|
91
|
-
unordered_map<string,
|
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
|
111
|
-
|
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
|
119
|
-
|
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
|
124
|
-
|
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
|
132
|
-
|
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
|
147
|
-
|
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
|
162
|
-
|
163
|
-
|
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
|
-
|
168
|
-
|
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
|
-
|
173
|
-
|
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
|
-
|
178
|
-
|
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
|
-
|
183
|
-
|
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
|
-
|
188
|
-
|
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
|
199
|
-
|
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
|
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
|
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(
|
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
|
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 = (
|
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<
|
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
|
250
|
-
|
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 = *
|
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(
|
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
|
277
|
-
|
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(
|
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
|
311
|
-
|
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 = *
|
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(
|
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
|
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
|
360
|
-
|
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(
|
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
|
386
|
-
|
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(
|
456
|
+
CreateValuesStruct(names, doc, vals, value_v, count);
|
408
457
|
break;
|
409
458
|
case LogicalTypeId::MAP:
|
410
|
-
CreateValuesMap(
|
459
|
+
CreateValuesMap(names, doc, vals, value_v, count);
|
411
460
|
break;
|
412
461
|
case LogicalTypeId::LIST:
|
413
|
-
CreateValuesList(
|
462
|
+
CreateValuesList(names, doc, vals, value_v, count);
|
414
463
|
break;
|
415
464
|
case LogicalTypeId::UNION:
|
416
|
-
CreateValuesUnion(
|
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 *
|
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 *
|
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 *
|
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 *
|
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
|
489
|
-
|
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 *
|
498
|
-
CreateValues(
|
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
|
-
|
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 (
|
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 ¶meters) {
|
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 *
|
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 *
|
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++) {
|