duckdb 1.3.1-dev6.0 → 1.3.2-dev0.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/core_functions/aggregate/distributive/arg_min_max.cpp +27 -39
- package/src/duckdb/extension/core_functions/aggregate/holistic/quantile.cpp +2 -3
- package/src/duckdb/extension/core_functions/include/core_functions/aggregate/quantile_sort_tree.hpp +1 -1
- package/src/duckdb/extension/core_functions/lambda_functions.cpp +16 -14
- package/src/duckdb/extension/core_functions/scalar/list/list_filter.cpp +3 -2
- package/src/duckdb/extension/core_functions/scalar/list/list_reduce.cpp +46 -10
- package/src/duckdb/extension/core_functions/scalar/list/list_transform.cpp +3 -2
- package/src/duckdb/extension/core_functions/scalar/random/random.cpp +3 -1
- package/src/duckdb/extension/icu/icu-datefunc.cpp +5 -3
- package/src/duckdb/extension/icu/icu-strptime.cpp +6 -1
- package/src/duckdb/extension/icu/icu-timezone.cpp +4 -0
- package/src/duckdb/extension/icu/icu_extension.cpp +7 -2
- package/src/duckdb/extension/icu/include/icu-datefunc.hpp +1 -1
- package/src/duckdb/extension/icu/include/icu-helpers.hpp +1 -1
- package/src/duckdb/extension/icu/third_party/icu/common/uloc.cpp +5 -5
- package/src/duckdb/extension/json/include/json_common.hpp +19 -0
- package/src/duckdb/extension/json/include/json_deserializer.hpp +1 -4
- package/src/duckdb/extension/json/include/json_functions.hpp +4 -4
- package/src/duckdb/extension/json/json_functions/json_serialize_sql.cpp +38 -17
- package/src/duckdb/extension/json/json_functions/json_table_in_out.cpp +11 -7
- package/src/duckdb/extension/json/json_functions.cpp +4 -4
- package/src/duckdb/extension/json/json_reader.cpp +1 -1
- package/src/duckdb/extension/parquet/column_reader.cpp +7 -1
- package/src/duckdb/extension/parquet/include/parquet_bss_decoder.hpp +2 -2
- package/src/duckdb/extension/parquet/include/parquet_dbp_encoder.hpp +2 -2
- package/src/duckdb/extension/parquet/include/parquet_reader.hpp +2 -1
- package/src/duckdb/extension/parquet/include/parquet_statistics.hpp +1 -1
- package/src/duckdb/extension/parquet/include/parquet_writer.hpp +3 -0
- package/src/duckdb/extension/parquet/include/writer/parquet_write_operators.hpp +3 -1
- package/src/duckdb/extension/parquet/include/writer/templated_column_writer.hpp +1 -1
- package/src/duckdb/extension/parquet/parquet_crypto.cpp +9 -5
- package/src/duckdb/extension/parquet/parquet_extension.cpp +26 -0
- package/src/duckdb/extension/parquet/parquet_float16.cpp +4 -2
- package/src/duckdb/extension/parquet/parquet_metadata.cpp +3 -3
- package/src/duckdb/extension/parquet/parquet_multi_file_info.cpp +12 -0
- package/src/duckdb/extension/parquet/parquet_reader.cpp +5 -4
- package/src/duckdb/extension/parquet/parquet_statistics.cpp +13 -3
- package/src/duckdb/extension/parquet/parquet_writer.cpp +1 -1
- package/src/duckdb/extension/parquet/reader/decimal_column_reader.cpp +1 -1
- package/src/duckdb/extension/parquet/reader/string_column_reader.cpp +1 -1
- package/src/duckdb/extension/parquet/reader/struct_column_reader.cpp +13 -4
- package/src/duckdb/extension/parquet/serialize_parquet.cpp +2 -0
- package/src/duckdb/src/catalog/catalog.cpp +10 -4
- package/src/duckdb/src/catalog/catalog_entry/duck_table_entry.cpp +4 -10
- package/src/duckdb/src/catalog/catalog_entry/schema_catalog_entry.cpp +1 -2
- package/src/duckdb/src/catalog/catalog_entry/sequence_catalog_entry.cpp +1 -1
- package/src/duckdb/src/catalog/catalog_entry/table_catalog_entry.cpp +2 -2
- package/src/duckdb/src/catalog/catalog_entry/type_catalog_entry.cpp +1 -1
- package/src/duckdb/src/catalog/catalog_search_path.cpp +7 -1
- package/src/duckdb/src/catalog/catalog_set.cpp +21 -1
- package/src/duckdb/src/common/adbc/adbc.cpp +1 -1
- package/src/duckdb/src/common/arrow/arrow_appender.cpp +17 -5
- package/src/duckdb/src/common/arrow/arrow_converter.cpp +23 -15
- package/src/duckdb/src/common/box_renderer.cpp +1 -2
- package/src/duckdb/src/common/enum_util.cpp +4 -3
- package/src/duckdb/src/common/local_file_system.cpp +13 -12
- package/src/duckdb/src/common/multi_file/multi_file_column_mapper.cpp +35 -12
- package/src/duckdb/src/common/multi_file/multi_file_reader.cpp +13 -3
- package/src/duckdb/src/common/string_util.cpp +7 -5
- package/src/duckdb/src/common/tree_renderer/graphviz_tree_renderer.cpp +4 -4
- package/src/duckdb/src/common/tree_renderer/html_tree_renderer.cpp +4 -4
- package/src/duckdb/src/common/tree_renderer/json_tree_renderer.cpp +4 -4
- package/src/duckdb/src/common/tree_renderer/text_tree_renderer.cpp +4 -4
- package/src/duckdb/src/common/types/row/tuple_data_segment.cpp +1 -1
- package/src/duckdb/src/common/types/uuid.cpp +5 -1
- package/src/duckdb/src/common/types.cpp +28 -0
- package/src/duckdb/src/common/virtual_file_system.cpp +5 -0
- package/src/duckdb/src/execution/column_binding_resolver.cpp +49 -30
- package/src/duckdb/src/execution/index/fixed_size_allocator.cpp +4 -0
- package/src/duckdb/src/execution/join_hashtable.cpp +10 -7
- package/src/duckdb/src/execution/operator/aggregate/physical_streaming_window.cpp +3 -3
- package/src/duckdb/src/execution/operator/csv_scanner/encode/csv_encoder.cpp +1 -1
- package/src/duckdb/src/execution/operator/csv_scanner/scanner/column_count_scanner.cpp +2 -1
- package/src/duckdb/src/execution/operator/csv_scanner/scanner/skip_scanner.cpp +1 -4
- package/src/duckdb/src/execution/operator/csv_scanner/scanner/string_value_scanner.cpp +53 -1
- package/src/duckdb/src/execution/operator/csv_scanner/sniffer/dialect_detection.cpp +58 -59
- package/src/duckdb/src/execution/operator/join/physical_hash_join.cpp +10 -5
- package/src/duckdb/src/execution/operator/persistent/physical_batch_copy_to_file.cpp +4 -0
- package/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp +18 -8
- package/src/duckdb/src/execution/operator/persistent/physical_export.cpp +1 -1
- package/src/duckdb/src/execution/operator/schema/physical_attach.cpp +1 -0
- package/src/duckdb/src/execution/physical_plan_generator.cpp +5 -5
- package/src/duckdb/src/function/cast/vector_cast_helpers.cpp +2 -1
- package/src/duckdb/src/function/function.cpp +4 -0
- package/src/duckdb/src/function/scalar/operator/arithmetic.cpp +6 -0
- package/src/duckdb/src/function/scalar/struct/remap_struct.cpp +10 -1
- package/src/duckdb/src/function/table/copy_csv.cpp +1 -0
- package/src/duckdb/src/function/table/version/pragma_version.cpp +3 -3
- package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +1 -0
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_table_entry.hpp +1 -1
- package/src/duckdb/src/include/duckdb/catalog/catalog_search_path.hpp +1 -1
- package/src/duckdb/src/include/duckdb/catalog/catalog_set.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/file_buffer.hpp +2 -2
- package/src/duckdb/src/include/duckdb/common/helper.hpp +9 -9
- package/src/duckdb/src/include/duckdb/common/hive_partitioning.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/multi_file/multi_file_column_mapper.hpp +3 -5
- package/src/duckdb/src/include/duckdb/common/multi_file/multi_file_reader.hpp +7 -0
- package/src/duckdb/src/include/duckdb/common/multi_file/multi_file_states.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/shadow_forbidden_functions.hpp +40 -0
- package/src/duckdb/src/include/duckdb/common/string.hpp +25 -2
- package/src/duckdb/src/include/duckdb/common/types/hugeint.hpp +20 -24
- package/src/duckdb/src/include/duckdb/common/types/uhugeint.hpp +20 -24
- package/src/duckdb/src/include/duckdb/common/types.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/unique_ptr.hpp +34 -8
- package/src/duckdb/src/include/duckdb/execution/column_binding_resolver.hpp +1 -0
- package/src/duckdb/src/include/duckdb/execution/join_hashtable.hpp +3 -2
- package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/column_count_scanner.hpp +3 -0
- package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/encode/csv_encoder.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp +15 -3
- package/src/duckdb/src/include/duckdb/function/cast/vector_cast_helpers.hpp +2 -2
- package/src/duckdb/src/include/duckdb/function/copy_function.hpp +7 -3
- package/src/duckdb/src/include/duckdb/function/function.hpp +1 -0
- package/src/duckdb/src/include/duckdb/function/function_binder.hpp +2 -1
- package/src/duckdb/src/include/duckdb/function/function_serialization.hpp +20 -12
- package/src/duckdb/src/include/duckdb/function/lambda_functions.hpp +4 -3
- package/src/duckdb/src/include/duckdb/function/scalar_function.hpp +3 -1
- package/src/duckdb/src/include/duckdb/logging/log_type.hpp +17 -0
- package/src/duckdb/src/include/duckdb/main/attached_database.hpp +1 -0
- package/src/duckdb/src/include/duckdb/main/client_properties.hpp +22 -6
- package/src/duckdb/src/include/duckdb/main/config.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/database_manager.hpp +4 -1
- package/src/duckdb/src/include/duckdb/main/extension_entries.hpp +27 -13
- package/src/duckdb/src/include/duckdb/main/secret/secret_manager.hpp +1 -0
- package/src/duckdb/src/include/duckdb/main/settings.hpp +11 -0
- package/src/duckdb/src/include/duckdb/optimizer/topn_optimizer.hpp +7 -1
- package/src/duckdb/src/include/duckdb/original/std/locale.hpp +10 -0
- package/src/duckdb/src/include/duckdb/original/std/memory.hpp +12 -0
- package/src/duckdb/src/include/duckdb/original/std/sstream.hpp +11 -0
- package/src/duckdb/src/include/duckdb/planner/expression_binder.hpp +5 -3
- package/src/duckdb/src/include/duckdb/storage/buffer/buffer_pool.hpp +4 -2
- package/src/duckdb/src/logging/log_manager.cpp +1 -0
- package/src/duckdb/src/logging/log_types.cpp +40 -0
- package/src/duckdb/src/main/attached_database.cpp +4 -0
- package/src/duckdb/src/main/client_context.cpp +1 -0
- package/src/duckdb/src/main/config.cpp +1 -0
- package/src/duckdb/src/main/database.cpp +1 -0
- package/src/duckdb/src/main/database_manager.cpp +19 -2
- package/src/duckdb/src/main/extension/extension_helper.cpp +4 -3
- package/src/duckdb/src/main/query_profiler.cpp +2 -2
- package/src/duckdb/src/main/query_result.cpp +1 -1
- package/src/duckdb/src/main/secret/secret_manager.cpp +2 -0
- package/src/duckdb/src/main/settings/autogenerated_settings.cpp +7 -0
- package/src/duckdb/src/main/settings/custom_settings.cpp +106 -34
- package/src/duckdb/src/optimizer/optimizer.cpp +1 -1
- package/src/duckdb/src/optimizer/topn_optimizer.cpp +18 -8
- package/src/duckdb/src/parallel/executor.cpp +5 -0
- package/src/duckdb/src/parser/parsed_data/create_sequence_info.cpp +1 -1
- package/src/duckdb/src/parser/transform/expression/transform_interval.cpp +5 -1
- package/src/duckdb/src/planner/binder/expression/bind_function_expression.cpp +21 -24
- package/src/duckdb/src/planner/binder/expression/bind_lambda.cpp +10 -8
- package/src/duckdb/src/planner/binder/expression/bind_operator_expression.cpp +3 -2
- package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +0 -4
- package/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp +3 -0
- package/src/duckdb/src/planner/binder/tableref/bind_table_function.cpp +3 -0
- package/src/duckdb/src/planner/expression/bound_cast_expression.cpp +3 -0
- package/src/duckdb/src/planner/expression/bound_columnref_expression.cpp +1 -1
- package/src/duckdb/src/planner/expression/bound_function_expression.cpp +0 -1
- package/src/duckdb/src/planner/expression/bound_reference_expression.cpp +1 -1
- package/src/duckdb/src/planner/expression_binder.cpp +4 -2
- package/src/duckdb/src/planner/logical_operator.cpp +2 -1
- package/src/duckdb/src/planner/subquery/flatten_dependent_join.cpp +4 -1
- package/src/duckdb/src/storage/buffer/block_handle.cpp +8 -0
- package/src/duckdb/src/storage/buffer/buffer_pool.cpp +44 -18
- package/src/duckdb/src/storage/caching_file_system.cpp +7 -7
- package/src/duckdb/src/storage/standard_buffer_manager.cpp +4 -3
- package/src/duckdb/src/storage/storage_info.cpp +2 -0
- package/src/duckdb/src/storage/wal_replay.cpp +9 -4
- package/src/duckdb/third_party/fmt/include/fmt/format.h +8 -1
- package/src/duckdb/third_party/fsst/libfsst.cpp +4 -3
- package/src/duckdb/third_party/httplib/httplib.hpp +25 -22
- package/src/duckdb/third_party/hyperloglog/sds.cpp +7 -3
- package/src/duckdb/third_party/libpg_query/src_common_keywords.cpp +8 -1
- package/src/duckdb/third_party/re2/re2/filtered_re2.h +8 -2
- package/src/duckdb/third_party/re2/re2/pod_array.h +7 -1
- package/src/duckdb/third_party/re2/re2/re2.cc +6 -2
- package/src/duckdb/third_party/re2/re2/set.cc +1 -1
- package/src/duckdb/third_party/re2/re2/set.h +7 -1
- package/src/duckdb/ub_src_logging.cpp +4 -4
package/package.json
CHANGED
@@ -21,11 +21,7 @@ struct ArgMinMaxStateBase {
|
|
21
21
|
}
|
22
22
|
|
23
23
|
template <class T>
|
24
|
-
static inline void
|
25
|
-
}
|
26
|
-
|
27
|
-
template <class T>
|
28
|
-
static inline void AssignValue(T &target, T new_value) {
|
24
|
+
static inline void AssignValue(T &target, T new_value, AggregateInputData &aggregate_input_data) {
|
29
25
|
target = new_value;
|
30
26
|
}
|
31
27
|
|
@@ -45,23 +41,21 @@ void ArgMinMaxStateBase::CreateValue(string_t &value) {
|
|
45
41
|
}
|
46
42
|
|
47
43
|
template <>
|
48
|
-
void ArgMinMaxStateBase::
|
49
|
-
if (!value.IsInlined()) {
|
50
|
-
delete[] value.GetData();
|
51
|
-
}
|
52
|
-
}
|
53
|
-
|
54
|
-
template <>
|
55
|
-
void ArgMinMaxStateBase::AssignValue(string_t &target, string_t new_value) {
|
56
|
-
DestroyValue(target);
|
44
|
+
void ArgMinMaxStateBase::AssignValue(string_t &target, string_t new_value, AggregateInputData &aggregate_input_data) {
|
57
45
|
if (new_value.IsInlined()) {
|
58
46
|
target = new_value;
|
59
47
|
} else {
|
60
48
|
// non-inlined string, need to allocate space for it
|
61
49
|
auto len = new_value.GetSize();
|
62
|
-
|
50
|
+
char *ptr;
|
51
|
+
if (!target.IsInlined() && target.GetSize() >= len) {
|
52
|
+
// Target has enough space, reuse ptr
|
53
|
+
ptr = target.GetPointer();
|
54
|
+
} else {
|
55
|
+
// Target might be too small, allocate
|
56
|
+
ptr = reinterpret_cast<char *>(aggregate_input_data.allocator.Allocate(len));
|
57
|
+
}
|
63
58
|
memcpy(ptr, new_value.GetData(), len);
|
64
|
-
|
65
59
|
target = string_t(ptr, UnsafeNumericCast<uint32_t>(len));
|
66
60
|
}
|
67
61
|
}
|
@@ -83,14 +77,6 @@ struct ArgMinMaxState : public ArgMinMaxStateBase {
|
|
83
77
|
CreateValue(arg);
|
84
78
|
CreateValue(value);
|
85
79
|
}
|
86
|
-
|
87
|
-
~ArgMinMaxState() {
|
88
|
-
if (is_initialized) {
|
89
|
-
DestroyValue(arg);
|
90
|
-
DestroyValue(value);
|
91
|
-
is_initialized = false;
|
92
|
-
}
|
93
|
-
}
|
94
80
|
};
|
95
81
|
|
96
82
|
template <class COMPARATOR, bool IGNORE_NULL>
|
@@ -106,16 +92,17 @@ struct ArgMinMaxBase {
|
|
106
92
|
}
|
107
93
|
|
108
94
|
template <class A_TYPE, class B_TYPE, class STATE>
|
109
|
-
static void Assign(STATE &state, const A_TYPE &x, const B_TYPE &y, const bool x_null
|
95
|
+
static void Assign(STATE &state, const A_TYPE &x, const B_TYPE &y, const bool x_null,
|
96
|
+
AggregateInputData &aggregate_input_data) {
|
110
97
|
if (IGNORE_NULL) {
|
111
|
-
STATE::template AssignValue<A_TYPE>(state.arg, x);
|
112
|
-
STATE::template AssignValue<B_TYPE>(state.value, y);
|
98
|
+
STATE::template AssignValue<A_TYPE>(state.arg, x, aggregate_input_data);
|
99
|
+
STATE::template AssignValue<B_TYPE>(state.value, y, aggregate_input_data);
|
113
100
|
} else {
|
114
101
|
state.arg_null = x_null;
|
115
102
|
if (!state.arg_null) {
|
116
|
-
STATE::template AssignValue<A_TYPE>(state.arg, x);
|
103
|
+
STATE::template AssignValue<A_TYPE>(state.arg, x, aggregate_input_data);
|
117
104
|
}
|
118
|
-
STATE::template AssignValue<B_TYPE>(state.value, y);
|
105
|
+
STATE::template AssignValue<B_TYPE>(state.value, y, aggregate_input_data);
|
119
106
|
}
|
120
107
|
}
|
121
108
|
|
@@ -123,7 +110,7 @@ struct ArgMinMaxBase {
|
|
123
110
|
static void Operation(STATE &state, const A_TYPE &x, const B_TYPE &y, AggregateBinaryInput &binary) {
|
124
111
|
if (!state.is_initialized) {
|
125
112
|
if (IGNORE_NULL || binary.right_mask.RowIsValid(binary.ridx)) {
|
126
|
-
Assign(state, x, y, !binary.left_mask.RowIsValid(binary.lidx));
|
113
|
+
Assign(state, x, y, !binary.left_mask.RowIsValid(binary.lidx), binary.input);
|
127
114
|
state.is_initialized = true;
|
128
115
|
}
|
129
116
|
} else {
|
@@ -134,17 +121,17 @@ struct ArgMinMaxBase {
|
|
134
121
|
template <class A_TYPE, class B_TYPE, class STATE>
|
135
122
|
static void Execute(STATE &state, A_TYPE x_data, B_TYPE y_data, AggregateBinaryInput &binary) {
|
136
123
|
if ((IGNORE_NULL || binary.right_mask.RowIsValid(binary.ridx)) && COMPARATOR::Operation(y_data, state.value)) {
|
137
|
-
Assign(state, x_data, y_data, !binary.left_mask.RowIsValid(binary.lidx));
|
124
|
+
Assign(state, x_data, y_data, !binary.left_mask.RowIsValid(binary.lidx), binary.input);
|
138
125
|
}
|
139
126
|
}
|
140
127
|
|
141
128
|
template <class STATE, class OP>
|
142
|
-
static void Combine(const STATE &source, STATE &target, AggregateInputData &) {
|
129
|
+
static void Combine(const STATE &source, STATE &target, AggregateInputData &aggregate_input_data) {
|
143
130
|
if (!source.is_initialized) {
|
144
131
|
return;
|
145
132
|
}
|
146
133
|
if (!target.is_initialized || COMPARATOR::Operation(source.value, target.value)) {
|
147
|
-
Assign(target, source.arg, source.value, source.arg_null);
|
134
|
+
Assign(target, source.arg, source.value, source.arg_null, aggregate_input_data);
|
148
135
|
target.is_initialized = true;
|
149
136
|
}
|
150
137
|
}
|
@@ -201,7 +188,8 @@ template <typename COMPARATOR, bool IGNORE_NULL, OrderType ORDER_TYPE,
|
|
201
188
|
class UPDATE_TYPE = SpecializedGenericArgMinMaxState>
|
202
189
|
struct VectorArgMinMaxBase : ArgMinMaxBase<COMPARATOR, IGNORE_NULL> {
|
203
190
|
template <class STATE>
|
204
|
-
static void Update(Vector inputs[], AggregateInputData
|
191
|
+
static void Update(Vector inputs[], AggregateInputData &aggregate_input_data, idx_t input_count,
|
192
|
+
Vector &state_vector, idx_t count) {
|
205
193
|
auto &arg = inputs[0];
|
206
194
|
UnifiedVectorFormat adata;
|
207
195
|
arg.ToUnifiedFormat(count, adata);
|
@@ -238,7 +226,7 @@ struct VectorArgMinMaxBase : ArgMinMaxBase<COMPARATOR, IGNORE_NULL> {
|
|
238
226
|
const auto sidx = sdata.sel->get_index(i);
|
239
227
|
auto &state = *states[sidx];
|
240
228
|
if (!state.is_initialized || COMPARATOR::template Operation<BY_TYPE>(bval, state.value)) {
|
241
|
-
STATE::template AssignValue<BY_TYPE>(state.value, bval);
|
229
|
+
STATE::template AssignValue<BY_TYPE>(state.value, bval, aggregate_input_data);
|
242
230
|
state.arg_null = arg_null;
|
243
231
|
// micro-adaptivity: it is common we overwrite the same state repeatedly
|
244
232
|
// e.g. when running arg_max(val, ts) and ts is sorted in ascending order
|
@@ -271,20 +259,20 @@ struct VectorArgMinMaxBase : ArgMinMaxBase<COMPARATOR, IGNORE_NULL> {
|
|
271
259
|
for (idx_t i = 0; i < assign_count; i++) {
|
272
260
|
const auto sidx = sdata.sel->get_index(sel.get_index(i));
|
273
261
|
auto &state = *states[sidx];
|
274
|
-
STATE::template AssignValue<ARG_TYPE>(state.arg, sort_key_data[i]);
|
262
|
+
STATE::template AssignValue<ARG_TYPE>(state.arg, sort_key_data[i], aggregate_input_data);
|
275
263
|
}
|
276
264
|
}
|
277
265
|
|
278
266
|
template <class STATE, class OP>
|
279
|
-
static void Combine(const STATE &source, STATE &target, AggregateInputData &) {
|
267
|
+
static void Combine(const STATE &source, STATE &target, AggregateInputData &aggregate_input_data) {
|
280
268
|
if (!source.is_initialized) {
|
281
269
|
return;
|
282
270
|
}
|
283
271
|
if (!target.is_initialized || COMPARATOR::Operation(source.value, target.value)) {
|
284
|
-
STATE::template AssignValue<typename STATE::BY_TYPE>(target.value, source.value);
|
272
|
+
STATE::template AssignValue<typename STATE::BY_TYPE>(target.value, source.value, aggregate_input_data);
|
285
273
|
target.arg_null = source.arg_null;
|
286
274
|
if (!target.arg_null) {
|
287
|
-
STATE::template AssignValue<typename STATE::ARG_TYPE>(target.arg, source.arg);
|
275
|
+
STATE::template AssignValue<typename STATE::ARG_TYPE>(target.arg, source.arg, aggregate_input_data);
|
288
276
|
}
|
289
277
|
target.is_initialized = true;
|
290
278
|
}
|
@@ -6,7 +6,6 @@
|
|
6
6
|
#include "duckdb/common/operator/abs.hpp"
|
7
7
|
#include "core_functions/aggregate/quantile_state.hpp"
|
8
8
|
#include "duckdb/common/types/timestamp.hpp"
|
9
|
-
#include "duckdb/common/queue.hpp"
|
10
9
|
#include "duckdb/common/serializer/serializer.hpp"
|
11
10
|
#include "duckdb/common/serializer/deserializer.hpp"
|
12
11
|
#include "duckdb/function/aggregate/sort_key_helpers.hpp"
|
@@ -588,7 +587,7 @@ AggregateFunction GetContinuousQuantileList(const LogicalType &type) {
|
|
588
587
|
//===--------------------------------------------------------------------===//
|
589
588
|
// Quantile binding
|
590
589
|
//===--------------------------------------------------------------------===//
|
591
|
-
static
|
590
|
+
static Value CheckQuantile(const Value &quantile_val) {
|
592
591
|
if (quantile_val.IsNull()) {
|
593
592
|
throw BinderException("QUANTILE parameter cannot be NULL");
|
594
593
|
}
|
@@ -820,7 +819,7 @@ struct ContinuousQuantileListFunction {
|
|
820
819
|
};
|
821
820
|
|
822
821
|
template <class OP>
|
823
|
-
AggregateFunction EmptyQuantileFunction(LogicalType input, LogicalType result, const LogicalType &extra_arg) {
|
822
|
+
AggregateFunction EmptyQuantileFunction(LogicalType input, const LogicalType &result, const LogicalType &extra_arg) {
|
824
823
|
AggregateFunction fun({std::move(input)}, std::move(result), nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
|
825
824
|
OP::Bind);
|
826
825
|
if (extra_arg.id() != LogicalTypeId::INVALID) {
|
package/src/duckdb/extension/core_functions/include/core_functions/aggregate/quantile_sort_tree.hpp
CHANGED
@@ -144,7 +144,7 @@ struct QuantileCompare {
|
|
144
144
|
const auto lval = accessor_l(lhs);
|
145
145
|
const auto rval = accessor_r(rhs);
|
146
146
|
|
147
|
-
return desc ? (rval
|
147
|
+
return desc ? LessThan::Operation(rval, lval) : LessThan::Operation(lval, rval);
|
148
148
|
}
|
149
149
|
};
|
150
150
|
|
@@ -244,28 +244,30 @@ unique_ptr<FunctionData> ListLambdaBindData::Deserialize(Deserializer &deseriali
|
|
244
244
|
//===--------------------------------------------------------------------===//
|
245
245
|
// LambdaFunctions
|
246
246
|
//===--------------------------------------------------------------------===//
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
throw BinderException("This lambda function only supports up to two lambda parameters!");
|
247
|
+
LogicalType LambdaFunctions::DetermineListChildType(const LogicalType &child_type) {
|
248
|
+
if (child_type.id() != LogicalTypeId::SQLNULL && child_type.id() != LogicalTypeId::UNKNOWN) {
|
249
|
+
if (child_type.id() == LogicalTypeId::ARRAY) {
|
250
|
+
return ArrayType::GetChildType(child_type);
|
251
|
+
} else if (child_type.id() == LogicalTypeId::LIST) {
|
252
|
+
return ListType::GetChildType(child_type);
|
253
|
+
}
|
254
|
+
throw InternalException("The first argument must be a list or array type");
|
256
255
|
}
|
256
|
+
|
257
|
+
return child_type;
|
257
258
|
}
|
258
259
|
|
259
|
-
LogicalType LambdaFunctions::
|
260
|
+
LogicalType LambdaFunctions::BindBinaryChildren(const vector<LogicalType> &function_child_types,
|
261
|
+
const idx_t parameter_idx) {
|
262
|
+
auto list_type = DetermineListChildType(function_child_types[0]);
|
263
|
+
|
260
264
|
switch (parameter_idx) {
|
261
265
|
case 0:
|
262
|
-
return
|
266
|
+
return list_type;
|
263
267
|
case 1:
|
264
|
-
return list_child_type;
|
265
|
-
case 2:
|
266
268
|
return LogicalType::BIGINT;
|
267
269
|
default:
|
268
|
-
throw BinderException("This lambda function only supports up to
|
270
|
+
throw BinderException("This lambda function only supports up to two lambda parameters!");
|
269
271
|
}
|
270
272
|
}
|
271
273
|
|
@@ -30,8 +30,9 @@ static unique_ptr<FunctionData> ListFilterBind(ClientContext &context, ScalarFun
|
|
30
30
|
return LambdaFunctions::ListLambdaBind(context, bound_function, arguments, has_index);
|
31
31
|
}
|
32
32
|
|
33
|
-
static LogicalType ListFilterBindLambda(
|
34
|
-
|
33
|
+
static LogicalType ListFilterBindLambda(ClientContext &context, const vector<LogicalType> &function_child_types,
|
34
|
+
const idx_t parameter_idx) {
|
35
|
+
return LambdaFunctions::BindBinaryChildren(function_child_types, parameter_idx);
|
35
36
|
}
|
36
37
|
|
37
38
|
ScalarFunction ListFilterFun::GetFunction() {
|
@@ -1,7 +1,6 @@
|
|
1
1
|
#include "core_functions/scalar/list_functions.hpp"
|
2
2
|
#include "duckdb/function/lambda_functions.hpp"
|
3
3
|
#include "duckdb/planner/expression/bound_cast_expression.hpp"
|
4
|
-
#include "duckdb/planner/expression/bound_function_expression.hpp"
|
5
4
|
|
6
5
|
namespace duckdb {
|
7
6
|
|
@@ -219,12 +218,6 @@ static unique_ptr<FunctionData> ListReduceBind(ClientContext &context, ScalarFun
|
|
219
218
|
|
220
219
|
arguments[0] = BoundCastExpression::AddArrayCastToList(context, std::move(arguments[0]));
|
221
220
|
|
222
|
-
auto &bound_lambda_expr = arguments[1]->Cast<BoundLambdaExpression>();
|
223
|
-
if (bound_lambda_expr.parameter_count < 2 || bound_lambda_expr.parameter_count > 3) {
|
224
|
-
throw BinderException("list_reduce expects a function with 2 or 3 arguments");
|
225
|
-
}
|
226
|
-
auto has_index = bound_lambda_expr.parameter_count == 3;
|
227
|
-
|
228
221
|
unique_ptr<FunctionData> bind_data = LambdaFunctions::ListLambdaPrepareBind(arguments, context, bound_function);
|
229
222
|
if (bind_data) {
|
230
223
|
return bind_data;
|
@@ -236,7 +229,7 @@ static unique_ptr<FunctionData> ListReduceBind(ClientContext &context, ScalarFun
|
|
236
229
|
bool has_initial = arguments.size() == 3;
|
237
230
|
if (has_initial) {
|
238
231
|
const auto initial_value_type = arguments[2]->return_type;
|
239
|
-
// Check if the initial value type is the same as the
|
232
|
+
// Check if the initial value type is the same as the return type of the lambda expression
|
240
233
|
if (list_child_type != initial_value_type) {
|
241
234
|
LogicalType max_logical_type;
|
242
235
|
const auto has_max_logical_type =
|
@@ -253,6 +246,12 @@ static unique_ptr<FunctionData> ListReduceBind(ClientContext &context, ScalarFun
|
|
253
246
|
}
|
254
247
|
}
|
255
248
|
|
249
|
+
auto &bound_lambda_expr = arguments[1]->Cast<BoundLambdaExpression>();
|
250
|
+
if (bound_lambda_expr.parameter_count < 2 || bound_lambda_expr.parameter_count > 3) {
|
251
|
+
throw BinderException("list_reduce expects a function with 2 or 3 arguments");
|
252
|
+
}
|
253
|
+
auto has_index = bound_lambda_expr.parameter_count == 3;
|
254
|
+
|
256
255
|
auto cast_lambda_expr =
|
257
256
|
BoundCastExpression::AddCastToType(context, std::move(bound_lambda_expr.lambda_expr), list_child_type);
|
258
257
|
if (!cast_lambda_expr) {
|
@@ -263,8 +262,45 @@ static unique_ptr<FunctionData> ListReduceBind(ClientContext &context, ScalarFun
|
|
263
262
|
has_initial);
|
264
263
|
}
|
265
264
|
|
266
|
-
|
267
|
-
|
265
|
+
LogicalType BindReduceChildren(ClientContext &context, const vector<LogicalType> &function_child_types,
|
266
|
+
const idx_t parameter_idx) {
|
267
|
+
auto list_child_type = LambdaFunctions::DetermineListChildType(function_child_types[0]);
|
268
|
+
|
269
|
+
// if there is an initial value, find the max logical type
|
270
|
+
if (function_child_types.size() == 3) {
|
271
|
+
// the initial value is the third child
|
272
|
+
constexpr idx_t initial_idx = 2;
|
273
|
+
|
274
|
+
const LogicalType initial_value_type = function_child_types[initial_idx];
|
275
|
+
if (initial_value_type != list_child_type) {
|
276
|
+
// we need to check if the initial value type is the same as the return type of the lambda expression
|
277
|
+
LogicalType max_logical_type;
|
278
|
+
const auto has_max_logical_type =
|
279
|
+
LogicalType::TryGetMaxLogicalType(context, list_child_type, initial_value_type, max_logical_type);
|
280
|
+
if (!has_max_logical_type) {
|
281
|
+
throw BinderException(
|
282
|
+
"The initial value type must be the same as the list child type or a common super type");
|
283
|
+
}
|
284
|
+
|
285
|
+
list_child_type = max_logical_type;
|
286
|
+
}
|
287
|
+
}
|
288
|
+
|
289
|
+
switch (parameter_idx) {
|
290
|
+
case 0:
|
291
|
+
return list_child_type;
|
292
|
+
case 1:
|
293
|
+
return list_child_type;
|
294
|
+
case 2:
|
295
|
+
return LogicalType::BIGINT;
|
296
|
+
default:
|
297
|
+
throw BinderException("This lambda function only supports up to three lambda parameters!");
|
298
|
+
}
|
299
|
+
}
|
300
|
+
|
301
|
+
static LogicalType ListReduceBindLambda(ClientContext &context, const vector<LogicalType> &function_child_types,
|
302
|
+
const idx_t parameter_idx) {
|
303
|
+
return BindReduceChildren(context, function_child_types, parameter_idx);
|
268
304
|
}
|
269
305
|
|
270
306
|
ScalarFunctionSet ListReduceFun::GetFunctions() {
|
@@ -22,8 +22,9 @@ static unique_ptr<FunctionData> ListTransformBind(ClientContext &context, Scalar
|
|
22
22
|
return LambdaFunctions::ListLambdaBind(context, bound_function, arguments, has_index);
|
23
23
|
}
|
24
24
|
|
25
|
-
static LogicalType ListTransformBindLambda(
|
26
|
-
|
25
|
+
static LogicalType ListTransformBindLambda(ClientContext &context, const vector<LogicalType> &function_child_types,
|
26
|
+
const idx_t parameter_idx) {
|
27
|
+
return LambdaFunctions::BindBinaryChildren(function_child_types, parameter_idx);
|
27
28
|
}
|
28
29
|
|
29
30
|
ScalarFunction ListTransformFun::GetFunction() {
|
@@ -29,7 +29,9 @@ struct ExtractTimestampUuidOperator {
|
|
29
29
|
}
|
30
30
|
|
31
31
|
// UUID v7 begins with a 48 bit big-endian Unix Epoch timestamp with millisecond granularity.
|
32
|
-
|
32
|
+
int64_t upper = input.upper;
|
33
|
+
// flip the top byte
|
34
|
+
upper ^= NumericLimits<int64_t>::Minimum();
|
33
35
|
int64_t unix_ts_milli = upper;
|
34
36
|
unix_ts_milli = unix_ts_milli >> 16;
|
35
37
|
|
@@ -82,10 +82,12 @@ bool ICUDateFunc::TrySetTimeZone(icu::Calendar *calendar, const string_t &tz_id)
|
|
82
82
|
return true;
|
83
83
|
}
|
84
84
|
|
85
|
-
void ICUDateFunc::SetTimeZone(icu::Calendar *calendar, const string_t &tz_id) {
|
85
|
+
void ICUDateFunc::SetTimeZone(icu::Calendar *calendar, const string_t &tz_id, string *error_message) {
|
86
86
|
string tz_str = tz_id.GetString();
|
87
|
-
auto tz = ICUHelpers::GetTimeZone(tz_str);
|
88
|
-
|
87
|
+
auto tz = ICUHelpers::GetTimeZone(tz_str, error_message);
|
88
|
+
if (tz) {
|
89
|
+
calendar->adoptTimeZone(tz.release());
|
90
|
+
}
|
89
91
|
}
|
90
92
|
|
91
93
|
timestamp_t ICUDateFunc::GetTimeUnsafe(icu::Calendar *calendar, uint64_t micros) {
|
@@ -293,7 +293,12 @@ struct ICUStrptime : public ICUDateFunc {
|
|
293
293
|
|
294
294
|
// Change TZ if one was provided.
|
295
295
|
if (tz.GetSize()) {
|
296
|
-
|
296
|
+
string error_msg;
|
297
|
+
SetTimeZone(calendar, tz, &error_msg);
|
298
|
+
if (!error_msg.empty()) {
|
299
|
+
HandleCastError::AssignError(error_msg, parameters);
|
300
|
+
mask.SetInvalid(idx);
|
301
|
+
}
|
297
302
|
}
|
298
303
|
|
299
304
|
// Now get the parts in the given time zone
|
@@ -247,6 +247,10 @@ struct ICUToNaiveTimestamp : public ICUDateFunc {
|
|
247
247
|
if (!input.context) {
|
248
248
|
throw InternalException("Missing context for TIMESTAMPTZ to TIMESTAMP cast.");
|
249
249
|
}
|
250
|
+
if (input.context->config.disable_timestamptz_casts) {
|
251
|
+
throw BinderException("Casting from TIMESTAMP WITH TIME ZONE to TIMESTAMP without an explicit time zone "
|
252
|
+
"has been disabled - use \"AT TIME ZONE ...\"");
|
253
|
+
}
|
250
254
|
|
251
255
|
auto cast_data = make_uniq<CastData>(make_uniq<BindData>(*input.context));
|
252
256
|
|
@@ -252,7 +252,7 @@ unique_ptr<icu::TimeZone> ICUHelpers::TryGetTimeZone(string &tz_str) {
|
|
252
252
|
return GetTimeZoneInternal(tz_str, candidates);
|
253
253
|
}
|
254
254
|
|
255
|
-
unique_ptr<icu::TimeZone> ICUHelpers::GetTimeZone(string &tz_str) {
|
255
|
+
unique_ptr<icu::TimeZone> ICUHelpers::GetTimeZone(string &tz_str, string *error_message) {
|
256
256
|
vector<string> candidates;
|
257
257
|
auto tz = GetTimeZoneInternal(tz_str, candidates);
|
258
258
|
if (tz) {
|
@@ -260,7 +260,12 @@ unique_ptr<icu::TimeZone> ICUHelpers::GetTimeZone(string &tz_str) {
|
|
260
260
|
}
|
261
261
|
string candidate_str =
|
262
262
|
StringUtil::CandidatesMessage(StringUtil::TopNJaroWinkler(candidates, tz_str), "Candidate time zones");
|
263
|
-
|
263
|
+
if (error_message) {
|
264
|
+
duckdb::stringstream ss;
|
265
|
+
ss << "Unknown TimeZone '" << tz_str << "'!\n" << candidate_str;
|
266
|
+
*error_message = ss.str();
|
267
|
+
return nullptr;
|
268
|
+
}
|
264
269
|
throw NotImplementedException("Unknown TimeZone '%s'!\n%s", tz_str, candidate_str);
|
265
270
|
}
|
266
271
|
|
@@ -50,7 +50,7 @@ struct ICUDateFunc {
|
|
50
50
|
//! Tries to set the time zone for the calendar and returns false if it is not valid.
|
51
51
|
static bool TrySetTimeZone(icu::Calendar *calendar, const string_t &tz_id);
|
52
52
|
//! Sets the time zone for the calendar. Throws if it is not valid
|
53
|
-
static void SetTimeZone(icu::Calendar *calendar, const string_t &tz_id);
|
53
|
+
static void SetTimeZone(icu::Calendar *calendar, const string_t &tz_id, string *error_message = nullptr);
|
54
54
|
//! Gets the timestamp from the calendar, throwing if it is not in range.
|
55
55
|
static bool TryGetTime(icu::Calendar *calendar, uint64_t micros, timestamp_t &result);
|
56
56
|
//! Gets the timestamp from the calendar, throwing if it is not in range.
|
@@ -18,7 +18,7 @@ struct ICUHelpers {
|
|
18
18
|
//! Tries to get a time zone - returns nullptr if the timezone is not found
|
19
19
|
static unique_ptr<icu::TimeZone> TryGetTimeZone(string &tz_str);
|
20
20
|
//! Gets a time zone - throws an error if the timezone is not found
|
21
|
-
static unique_ptr<icu::TimeZone> GetTimeZone(string &tz_str);
|
21
|
+
static unique_ptr<icu::TimeZone> GetTimeZone(string &tz_str, string *error_message = nullptr);
|
22
22
|
|
23
23
|
static TimestampComponents GetComponents(timestamp_tz_t ts, icu::Calendar *calendar);
|
24
24
|
|
@@ -45,8 +45,8 @@
|
|
45
45
|
#include "uenumimp.h"
|
46
46
|
#include "uassert.h"
|
47
47
|
#include "charstr.h"
|
48
|
-
|
49
48
|
#include <stdio.h> /* for sprintf */
|
49
|
+
#include "duckdb/common/string_util.hpp"
|
50
50
|
|
51
51
|
U_NAMESPACE_USE
|
52
52
|
|
@@ -2229,7 +2229,7 @@ uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable, UAcceptResult
|
|
2229
2229
|
}
|
2230
2230
|
|
2231
2231
|
for(s=httpAcceptLanguage;s&&*s;) {
|
2232
|
-
while(
|
2232
|
+
while(duckdb::StringUtil::CharacterIsSpace(*s)) /* eat space at the beginning */
|
2233
2233
|
s++;
|
2234
2234
|
itemEnd=uprv_strchr(s,',');
|
2235
2235
|
paramEnd=uprv_strchr(s,';');
|
@@ -2242,13 +2242,13 @@ uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable, UAcceptResult
|
|
2242
2242
|
if(*t=='q') {
|
2243
2243
|
t++;
|
2244
2244
|
}
|
2245
|
-
while(
|
2245
|
+
while(duckdb::StringUtil::CharacterIsSpace(*t)) {
|
2246
2246
|
t++;
|
2247
2247
|
}
|
2248
2248
|
if(*t=='=') {
|
2249
2249
|
t++;
|
2250
2250
|
}
|
2251
|
-
while(
|
2251
|
+
while(duckdb::StringUtil::CharacterIsSpace(*t)) {
|
2252
2252
|
t++;
|
2253
2253
|
}
|
2254
2254
|
items[n].q = (float)_uloc_strtod(t,NULL);
|
@@ -2259,7 +2259,7 @@ uloc_acceptLanguageFromHTTP(char *result, int32_t resultAvailable, UAcceptResult
|
|
2259
2259
|
}
|
2260
2260
|
items[n].dummy=0;
|
2261
2261
|
/* eat spaces prior to semi */
|
2262
|
-
for(t=(paramEnd-1);(paramEnd>s)&&
|
2262
|
+
for(t=(paramEnd-1);(paramEnd>s)&&duckdb::StringUtil::CharacterIsSpace(*t);t--)
|
2263
2263
|
;
|
2264
2264
|
int32_t slen = static_cast<int32_t>(((t+1)-s));
|
2265
2265
|
if(slen > ULOC_FULLNAME_CAPACITY) {
|
@@ -360,4 +360,23 @@ inline char *JSONCommon::WriteVal(yyjson_mut_val *val, yyjson_alc *alc, idx_t &l
|
|
360
360
|
return yyjson_mut_val_write_opts(val, JSONCommon::WRITE_FLAG, alc, reinterpret_cast<size_t *>(&len), nullptr);
|
361
361
|
}
|
362
362
|
|
363
|
+
struct yyjson_doc_deleter {
|
364
|
+
void operator()(yyjson_doc *doc) {
|
365
|
+
if (doc) {
|
366
|
+
yyjson_doc_free(doc);
|
367
|
+
}
|
368
|
+
}
|
369
|
+
};
|
370
|
+
|
371
|
+
struct yyjson_mut_doc_deleter {
|
372
|
+
void operator()(yyjson_mut_doc *doc) {
|
373
|
+
if (doc) {
|
374
|
+
yyjson_mut_doc_free(doc);
|
375
|
+
}
|
376
|
+
}
|
377
|
+
};
|
378
|
+
|
379
|
+
using yyjson_doc_ptr = unique_ptr<yyjson_doc, yyjson_doc_deleter>;
|
380
|
+
using yyjson_mut_doc_ptr = unique_ptr<yyjson_mut_doc, yyjson_mut_doc_deleter>;
|
381
|
+
|
363
382
|
} // namespace duckdb
|
@@ -6,13 +6,10 @@ namespace duckdb {
|
|
6
6
|
|
7
7
|
class JsonDeserializer : public Deserializer {
|
8
8
|
public:
|
9
|
-
JsonDeserializer(yyjson_val *val,
|
9
|
+
JsonDeserializer(yyjson_val *val, const yyjson_doc_ptr &doc) : doc(doc.get()) {
|
10
10
|
deserialize_enum_from_string = true;
|
11
11
|
stack.emplace_back(val);
|
12
12
|
}
|
13
|
-
~JsonDeserializer() {
|
14
|
-
yyjson_doc_free(doc);
|
15
|
-
}
|
16
13
|
|
17
14
|
private:
|
18
15
|
struct StackFrame {
|
@@ -27,7 +27,7 @@ public:
|
|
27
27
|
JSONReadFunctionData(bool constant, string path_p, idx_t len, JSONCommon::JSONPathType path_type);
|
28
28
|
unique_ptr<FunctionData> Copy() const override;
|
29
29
|
bool Equals(const FunctionData &other_p) const override;
|
30
|
-
static JSONCommon::JSONPathType CheckPath(const Value &path_val, string &path,
|
30
|
+
static JSONCommon::JSONPathType CheckPath(const Value &path_val, string &path, idx_t &len);
|
31
31
|
static unique_ptr<FunctionData> Bind(ClientContext &context, ScalarFunction &bound_function,
|
32
32
|
vector<unique_ptr<Expression>> &arguments);
|
33
33
|
|
@@ -36,12 +36,12 @@ public:
|
|
36
36
|
const string path;
|
37
37
|
const JSONCommon::JSONPathType path_type;
|
38
38
|
const char *ptr;
|
39
|
-
const
|
39
|
+
const idx_t len;
|
40
40
|
};
|
41
41
|
|
42
42
|
struct JSONReadManyFunctionData : public FunctionData {
|
43
43
|
public:
|
44
|
-
JSONReadManyFunctionData(vector<string> paths_p, vector<
|
44
|
+
JSONReadManyFunctionData(vector<string> paths_p, vector<idx_t> lens_p);
|
45
45
|
unique_ptr<FunctionData> Copy() const override;
|
46
46
|
bool Equals(const FunctionData &other_p) const override;
|
47
47
|
static unique_ptr<FunctionData> Bind(ClientContext &context, ScalarFunction &bound_function,
|
@@ -50,7 +50,7 @@ public:
|
|
50
50
|
public:
|
51
51
|
const vector<string> paths;
|
52
52
|
vector<const char *> ptrs;
|
53
|
-
const vector<
|
53
|
+
const vector<idx_t> lens;
|
54
54
|
};
|
55
55
|
|
56
56
|
struct JSONFunctionLocalState : public FunctionLocalState {
|