duckdb 0.8.1-dev96.0 → 0.8.2-dev1.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/binding.gyp +8 -8
- package/package.json +3 -1
- package/src/duckdb/extension/icu/icu-datepart.cpp +1 -1
- package/src/duckdb/extension/icu/icu-extension.cpp +1 -1
- package/src/duckdb/extension/icu/icu-makedate.cpp +5 -4
- package/src/duckdb/extension/icu/icu-strptime.cpp +1 -1
- package/src/duckdb/extension/icu/third_party/icu/i18n/nfsubs.cpp +0 -2
- package/src/duckdb/extension/json/buffered_json_reader.cpp +23 -14
- package/src/duckdb/extension/json/include/buffered_json_reader.hpp +6 -6
- package/src/duckdb/extension/json/include/json_common.hpp +12 -2
- package/src/duckdb/extension/json/include/json_scan.hpp +5 -2
- package/src/duckdb/extension/json/json_functions/json_contains.cpp +5 -0
- package/src/duckdb/extension/json/json_functions/json_create.cpp +10 -10
- package/src/duckdb/extension/json/json_functions/json_merge_patch.cpp +2 -2
- package/src/duckdb/extension/json/json_functions/json_serialize_sql.cpp +2 -2
- package/src/duckdb/extension/json/json_functions/json_structure.cpp +5 -3
- package/src/duckdb/extension/json/json_functions/json_transform.cpp +11 -11
- package/src/duckdb/extension/json/json_functions/read_json.cpp +2 -1
- package/src/duckdb/extension/json/json_functions.cpp +6 -3
- package/src/duckdb/extension/json/json_scan.cpp +43 -27
- package/src/duckdb/extension/parquet/column_reader.cpp +5 -1
- package/src/duckdb/extension/parquet/include/decode_utils.hpp +6 -0
- package/src/duckdb/extension/parquet/parquet-extension.cpp +26 -1
- package/src/duckdb/src/catalog/catalog.cpp +5 -17
- package/src/duckdb/src/catalog/catalog_entry/duck_table_entry.cpp +7 -1
- package/src/duckdb/src/catalog/catalog_entry/table_catalog_entry.cpp +121 -0
- package/src/duckdb/src/catalog/catalog_search_path.cpp +49 -12
- package/src/duckdb/src/catalog/default/default_types.cpp +9 -84
- package/src/duckdb/src/common/adbc/adbc.cpp +118 -12
- package/src/duckdb/src/common/adbc/driver_manager.cpp +0 -20
- package/src/duckdb/src/common/arrow/arrow_converter.cpp +11 -12
- package/src/duckdb/src/common/arrow/arrow_wrapper.cpp +4 -3
- package/src/duckdb/src/common/exception.cpp +4 -1
- package/src/duckdb/src/common/exception_format_value.cpp +24 -15
- package/src/duckdb/src/common/multi_file_reader.cpp +3 -0
- package/src/duckdb/src/common/random_engine.cpp +1 -1
- package/src/duckdb/src/common/types/row/row_data_collection_scanner.cpp +5 -4
- package/src/duckdb/src/common/types/row/tuple_data_scatter_gather.cpp +44 -7
- package/src/duckdb/src/common/types/time.cpp +2 -8
- package/src/duckdb/src/common/types/timestamp.cpp +37 -1
- package/src/duckdb/src/common/types/value.cpp +1 -0
- package/src/duckdb/src/common/types.cpp +4 -0
- package/src/duckdb/src/core_functions/aggregate/algebraic/avg.cpp +30 -33
- package/src/duckdb/src/core_functions/aggregate/algebraic/covar.cpp +0 -4
- package/src/duckdb/src/core_functions/aggregate/distributive/approx_count.cpp +30 -33
- package/src/duckdb/src/core_functions/aggregate/distributive/arg_min_max.cpp +52 -65
- package/src/duckdb/src/core_functions/aggregate/distributive/bitagg.cpp +48 -48
- package/src/duckdb/src/core_functions/aggregate/distributive/bitstring_agg.cpp +39 -40
- package/src/duckdb/src/core_functions/aggregate/distributive/bool.cpp +32 -32
- package/src/duckdb/src/core_functions/aggregate/distributive/entropy.cpp +34 -34
- package/src/duckdb/src/core_functions/aggregate/distributive/kurtosis.cpp +30 -31
- package/src/duckdb/src/core_functions/aggregate/distributive/minmax.cpp +88 -100
- package/src/duckdb/src/core_functions/aggregate/distributive/product.cpp +17 -17
- package/src/duckdb/src/core_functions/aggregate/distributive/skew.cpp +25 -27
- package/src/duckdb/src/core_functions/aggregate/distributive/string_agg.cpp +37 -38
- package/src/duckdb/src/core_functions/aggregate/distributive/sum.cpp +22 -22
- package/src/duckdb/src/core_functions/aggregate/holistic/approximate_quantile.cpp +44 -80
- package/src/duckdb/src/core_functions/aggregate/holistic/mode.cpp +49 -51
- package/src/duckdb/src/core_functions/aggregate/holistic/quantile.cpp +104 -122
- package/src/duckdb/src/core_functions/aggregate/holistic/reservoir_quantile.cpp +57 -93
- package/src/duckdb/src/core_functions/aggregate/nested/histogram.cpp +22 -23
- package/src/duckdb/src/core_functions/aggregate/nested/list.cpp +18 -19
- package/src/duckdb/src/core_functions/aggregate/regression/regr_avg.cpp +16 -18
- package/src/duckdb/src/core_functions/aggregate/regression/regr_intercept.cpp +22 -25
- package/src/duckdb/src/core_functions/aggregate/regression/regr_r2.cpp +19 -24
- package/src/duckdb/src/core_functions/aggregate/regression/regr_sxx_syy.cpp +18 -23
- package/src/duckdb/src/core_functions/aggregate/regression/regr_sxy.cpp +14 -18
- package/src/duckdb/src/core_functions/function_list.cpp +1 -0
- package/src/duckdb/src/core_functions/scalar/date/date_part.cpp +1 -1
- package/src/duckdb/src/core_functions/scalar/date/make_date.cpp +3 -0
- package/src/duckdb/src/core_functions/scalar/generic/system_functions.cpp +14 -0
- package/src/duckdb/src/core_functions/scalar/list/array_slice.cpp +1 -1
- package/src/duckdb/src/core_functions/scalar/list/list_aggregates.cpp +23 -6
- package/src/duckdb/src/core_functions/scalar/list/list_lambdas.cpp +1 -2
- package/src/duckdb/src/core_functions/scalar/map/map_concat.cpp +3 -0
- package/src/duckdb/src/core_functions/scalar/math/numeric.cpp +3 -3
- package/src/duckdb/src/execution/index/art/art.cpp +80 -7
- package/src/duckdb/src/execution/index/art/fixed_size_allocator.cpp +20 -1
- package/src/duckdb/src/execution/index/art/leaf.cpp +11 -11
- package/src/duckdb/src/execution/index/art/leaf_segment.cpp +10 -0
- package/src/duckdb/src/execution/index/art/node.cpp +48 -35
- package/src/duckdb/src/execution/index/art/node16.cpp +3 -0
- package/src/duckdb/src/execution/index/art/node256.cpp +1 -0
- package/src/duckdb/src/execution/index/art/node4.cpp +3 -0
- package/src/duckdb/src/execution/index/art/node48.cpp +2 -0
- package/src/duckdb/src/execution/index/art/prefix.cpp +2 -0
- package/src/duckdb/src/execution/join_hashtable.cpp +2 -0
- package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +26 -9
- package/src/duckdb/src/execution/operator/helper/physical_reset.cpp +5 -2
- package/src/duckdb/src/execution/operator/helper/physical_set.cpp +5 -1
- package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +3 -6
- package/src/duckdb/src/execution/operator/projection/physical_tableinout_function.cpp +1 -0
- package/src/duckdb/src/execution/operator/projection/physical_unnest.cpp +8 -3
- package/src/duckdb/src/execution/operator/schema/physical_attach.cpp +0 -1
- package/src/duckdb/src/execution/operator/schema/physical_create_index.cpp +29 -3
- package/src/duckdb/src/execution/reservoir_sample.cpp +18 -4
- package/src/duckdb/src/function/aggregate/distributive/count.cpp +159 -21
- package/src/duckdb/src/function/aggregate/distributive/first.cpp +67 -74
- package/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp +7 -7
- package/src/duckdb/src/function/cast/list_casts.cpp +2 -4
- package/src/duckdb/src/function/pragma/pragma_queries.cpp +33 -23
- package/src/duckdb/src/function/scalar/list/list_extract.cpp +1 -1
- package/src/duckdb/src/function/scalar/operators/arithmetic.cpp +1 -1
- package/src/duckdb/src/function/scalar/string/regexp/regexp_util.cpp +6 -2
- package/src/duckdb/src/function/scalar/system/aggregate_export.cpp +2 -2
- package/src/duckdb/src/function/table/arrow.cpp +2 -2
- package/src/duckdb/src/function/table/checkpoint.cpp +3 -0
- package/src/duckdb/src/function/table/read_csv.cpp +15 -17
- package/src/duckdb/src/function/table/repeat.cpp +3 -0
- package/src/duckdb/src/function/table/repeat_row.cpp +8 -1
- package/src/duckdb/src/function/table/system/pragma_storage_info.cpp +4 -4
- package/src/duckdb/src/function/table/system/test_vector_types.cpp +81 -25
- package/src/duckdb/src/function/table/table_scan.cpp +2 -2
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +0 -3
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_table_entry.hpp +2 -0
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_catalog_entry.hpp +11 -1
- package/src/duckdb/src/include/duckdb/catalog/catalog_search_path.hpp +8 -2
- package/src/duckdb/src/include/duckdb/catalog/default/builtin_types/types.hpp +97 -0
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_appender.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_converter.hpp +2 -3
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_options.hpp +8 -1
- package/src/duckdb/src/include/duckdb/common/arrow/result_arrow_wrapper.hpp +0 -1
- package/src/duckdb/src/include/duckdb/common/bit_utils.hpp +16 -22
- package/src/duckdb/src/include/duckdb/common/exception.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/types/time.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/types/timestamp.hpp +4 -14
- package/src/duckdb/src/include/duckdb/common/vector_operations/aggregate_executor.hpp +92 -57
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/algebraic/corr.hpp +20 -24
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/algebraic/covar.hpp +36 -39
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/algebraic/stddev.hpp +57 -53
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/regression/regr_count.hpp +8 -9
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/regression/regr_slope.hpp +16 -18
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/sum_helpers.hpp +7 -8
- package/src/duckdb/src/include/duckdb/core_functions/scalar/generic_functions.hpp +9 -0
- package/src/duckdb/src/include/duckdb/core_functions/scalar/map_functions.hpp +2 -6
- package/src/duckdb/src/include/duckdb/core_functions/scalar/string_functions.hpp +16 -36
- package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +10 -4
- package/src/duckdb/src/include/duckdb/execution/index/art/fixed_size_allocator.hpp +3 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/leaf.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/index/art/leaf_segment.hpp +2 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/node.hpp +13 -3
- package/src/duckdb/src/include/duckdb/execution/index/art/node48.hpp +1 -0
- package/src/duckdb/src/include/duckdb/function/aggregate_function.hpp +9 -30
- package/src/duckdb/src/include/duckdb/function/aggregate_state.hpp +95 -0
- package/src/duckdb/src/include/duckdb/function/function_serialization.hpp +4 -2
- package/src/duckdb/src/include/duckdb/function/scalar/nested_functions.hpp +1 -1
- package/src/duckdb/src/include/duckdb/function/scalar_function.hpp +2 -1
- package/src/duckdb/src/include/duckdb/function/table_function.hpp +3 -2
- package/src/duckdb/src/include/duckdb/main/attached_database.hpp +4 -1
- package/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp +3 -1
- package/src/duckdb/src/include/duckdb/main/config.hpp +5 -0
- package/src/duckdb/src/include/duckdb/main/database_manager.hpp +1 -0
- package/src/duckdb/src/include/duckdb/main/extension_entries.hpp +142 -136
- package/src/duckdb/src/include/duckdb/main/query_result.hpp +6 -0
- package/src/duckdb/src/include/duckdb/main/settings.hpp +19 -0
- package/src/duckdb/src/include/duckdb/optimizer/unnest_rewriter.hpp +4 -0
- package/src/duckdb/src/include/duckdb/parallel/meta_pipeline.hpp +12 -3
- package/src/duckdb/src/include/duckdb/parser/parser.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/tableref/emptytableref.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/tableref/pivotref.hpp +2 -2
- package/src/duckdb/src/include/duckdb/parser/transformer.hpp +0 -2
- package/src/duckdb/src/include/duckdb/planner/bind_context.hpp +1 -1
- package/src/duckdb/src/include/duckdb/planner/bound_result_modifier.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression_binder.hpp +1 -1
- package/src/duckdb/src/include/duckdb/planner/logical_operator.hpp +5 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_copy_to_file.hpp +6 -2
- package/src/duckdb/src/include/duckdb/planner/operator/logical_execute.hpp +4 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_explain.hpp +5 -1
- package/src/duckdb/src/include/duckdb/planner/operator/logical_get.hpp +5 -1
- package/src/duckdb/src/include/duckdb/planner/operator/logical_pragma.hpp +6 -2
- package/src/duckdb/src/include/duckdb/planner/operator/logical_prepare.hpp +4 -0
- package/src/duckdb/src/include/duckdb/storage/compression/chimp/algorithm/byte_reader.hpp +4 -0
- package/src/duckdb/src/include/duckdb/storage/data_table.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/in_memory_block_manager.hpp +13 -13
- package/src/duckdb/src/include/duckdb/storage/index.hpp +4 -2
- package/src/duckdb/src/include/duckdb/storage/storage_extension.hpp +0 -6
- package/src/duckdb/src/include/duckdb/storage/table/column_data.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/table/list_column_data.hpp +2 -1
- package/src/duckdb/src/include/duckdb/storage/table/row_group.hpp +2 -2
- package/src/duckdb/src/include/duckdb/storage/table/row_group_collection.hpp +2 -1
- package/src/duckdb/src/include/duckdb/storage/table/standard_column_data.hpp +2 -1
- package/src/duckdb/src/include/duckdb/storage/table/struct_column_data.hpp +2 -1
- package/src/duckdb/src/include/duckdb/storage/table_storage_info.hpp +0 -2
- package/src/duckdb/src/main/attached_database.cpp +8 -0
- package/src/duckdb/src/main/capi/arrow-c.cpp +4 -4
- package/src/duckdb/src/main/capi/config-c.cpp +2 -5
- package/src/duckdb/src/main/client_context.cpp +4 -3
- package/src/duckdb/src/main/config.cpp +2 -0
- package/src/duckdb/src/main/database.cpp +1 -0
- package/src/duckdb/src/main/database_manager.cpp +21 -0
- package/src/duckdb/src/main/query_result.cpp +6 -2
- package/src/duckdb/src/main/settings/settings.cpp +41 -6
- package/src/duckdb/src/optimizer/unnest_rewriter.cpp +27 -16
- package/src/duckdb/src/parallel/executor.cpp +38 -14
- package/src/duckdb/src/parallel/meta_pipeline.cpp +17 -3
- package/src/duckdb/src/parser/column_definition.cpp +5 -8
- package/src/duckdb/src/parser/parsed_data/create_info.cpp +0 -3
- package/src/duckdb/src/parser/parser.cpp +95 -35
- package/src/duckdb/src/parser/transform/expression/transform_function.cpp +1 -0
- package/src/duckdb/src/parser/transform/expression/transform_operator.cpp +3 -0
- package/src/duckdb/src/parser/transform/helpers/nodetype_to_string.cpp +0 -2
- package/src/duckdb/src/parser/transform/statement/transform_drop.cpp +0 -3
- package/src/duckdb/src/parser/transform/tableref/transform_pivot.cpp +3 -0
- package/src/duckdb/src/parser/transformer.cpp +0 -2
- package/src/duckdb/src/planner/bind_context.cpp +3 -4
- package/src/duckdb/src/planner/binder/expression/bind_function_expression.cpp +0 -2
- package/src/duckdb/src/planner/binder/expression/bind_positional_reference_expression.cpp +8 -3
- package/src/duckdb/src/planner/binder/query_node/bind_select_node.cpp +31 -15
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +0 -27
- package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +18 -1
- package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +0 -25
- package/src/duckdb/src/planner/binder/statement/bind_update.cpp +2 -114
- package/src/duckdb/src/planner/binder/tableref/bind_pivot.cpp +6 -1
- package/src/duckdb/src/planner/binder/tableref/bind_table_function.cpp +5 -0
- package/src/duckdb/src/planner/bound_result_modifier.cpp +14 -0
- package/src/duckdb/src/planner/expression/bound_aggregate_expression.cpp +6 -5
- package/src/duckdb/src/planner/expression/bound_default_expression.cpp +7 -1
- package/src/duckdb/src/planner/expression.cpp +3 -0
- package/src/duckdb/src/planner/expression_binder.cpp +3 -2
- package/src/duckdb/src/planner/operator/logical_distinct.cpp +5 -4
- package/src/duckdb/src/planner/operator/logical_pivot.cpp +14 -2
- package/src/duckdb/src/planner/planner.cpp +5 -15
- package/src/duckdb/src/storage/data_table.cpp +10 -8
- package/src/duckdb/src/storage/index.cpp +13 -0
- package/src/duckdb/src/storage/storage_manager.cpp +6 -0
- package/src/duckdb/src/storage/table/column_data.cpp +7 -3
- package/src/duckdb/src/storage/table/list_column_data.cpp +5 -4
- package/src/duckdb/src/storage/table/row_group.cpp +4 -3
- package/src/duckdb/src/storage/table/row_group_collection.cpp +6 -3
- package/src/duckdb/src/storage/table/standard_column_data.cpp +4 -3
- package/src/duckdb/src/storage/table/struct_column_data.cpp +4 -3
- package/src/duckdb/src/storage/wal_replay.cpp +4 -5
- package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +0 -1
- package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +0 -14
- package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +12828 -12956
- package/src/duckdb/third_party/zstd/compress/zstd_compress.cpp +3 -0
- package/src/duckdb/third_party/zstd/include/zstd/compress/zstd_cwksp.h +4 -0
- package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +5 -5
- package/src/duckdb/ub_src_parser_transform_statement.cpp +0 -2
- package/test/extension.test.ts +11 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_database_info.hpp +0 -46
- package/src/duckdb/src/parser/transform/statement/transform_create_database.cpp +0 -27
@@ -244,14 +244,13 @@ unique_ptr<GlobalTableFunctionState> JSONGlobalTableFunctionState::Init(ClientCo
|
|
244
244
|
|
245
245
|
idx_t JSONGlobalTableFunctionState::MaxThreads() const {
|
246
246
|
auto &bind_data = state.bind_data;
|
247
|
-
if (bind_data.options.format == JSONFormat::NEWLINE_DELIMITED
|
248
|
-
bind_data.options.compression == FileCompressionType::UNCOMPRESSED) {
|
247
|
+
if (bind_data.options.format == JSONFormat::NEWLINE_DELIMITED) {
|
249
248
|
return state.system_threads;
|
250
249
|
}
|
251
250
|
|
252
251
|
if (!state.json_readers.empty() && state.json_readers[0]->IsOpen()) {
|
253
252
|
auto &reader = *state.json_readers[0];
|
254
|
-
if (reader.
|
253
|
+
if (reader.GetFormat() == JSONFormat::NEWLINE_DELIMITED) { // Auto-detected NDJSON
|
255
254
|
return state.system_threads;
|
256
255
|
}
|
257
256
|
}
|
@@ -298,6 +297,7 @@ idx_t JSONScanLocalState::ReadNext(JSONScanGlobalState &gstate) {
|
|
298
297
|
if (!ReadNextBuffer(gstate)) {
|
299
298
|
return scan_count;
|
300
299
|
}
|
300
|
+
D_ASSERT(buffer_size != 0);
|
301
301
|
if (current_buffer_handle->buffer_index != 0 && current_reader->GetFormat() == JSONFormat::NEWLINE_DELIMITED) {
|
302
302
|
ReconstructFirstObject(gstate);
|
303
303
|
scan_count++;
|
@@ -308,8 +308,8 @@ idx_t JSONScanLocalState::ReadNext(JSONScanGlobalState &gstate) {
|
|
308
308
|
return scan_count;
|
309
309
|
}
|
310
310
|
|
311
|
-
static inline const char *NextNewline(
|
312
|
-
return (
|
311
|
+
static inline const char *NextNewline(char *ptr, idx_t size) {
|
312
|
+
return char_ptr_cast(memchr(ptr, '\n', size));
|
313
313
|
}
|
314
314
|
|
315
315
|
static inline const char *PreviousNewline(const char *ptr) {
|
@@ -455,7 +455,21 @@ void JSONScanLocalState::ThrowInvalidAtEndError() {
|
|
455
455
|
throw InvalidInputException("Invalid JSON detected at the end of file \"%s\".", current_reader->GetFileName());
|
456
456
|
}
|
457
457
|
|
458
|
-
|
458
|
+
bool JSONScanLocalState::IsParallel(JSONScanGlobalState &gstate) const {
|
459
|
+
if (bind_data.files.size() >= gstate.system_threads) {
|
460
|
+
// More files than threads, just parallelize over the files
|
461
|
+
return false;
|
462
|
+
}
|
463
|
+
|
464
|
+
if (current_reader->GetFormat() == JSONFormat::NEWLINE_DELIMITED) {
|
465
|
+
// NDJSON can be read in parallel
|
466
|
+
return true;
|
467
|
+
}
|
468
|
+
|
469
|
+
return false;
|
470
|
+
}
|
471
|
+
|
472
|
+
static pair<JSONFormat, JSONRecordType> DetectFormatAndRecordType(char *const buffer_ptr, const idx_t buffer_size,
|
459
473
|
yyjson_alc *alc) {
|
460
474
|
// First we do the easy check whether it's NEWLINE_DELIMITED
|
461
475
|
auto line_end = NextNewline(buffer_ptr, buffer_size);
|
@@ -464,7 +478,7 @@ static pair<JSONFormat, JSONRecordType> DetectFormatAndRecordType(const char *co
|
|
464
478
|
SkipWhitespace(buffer_ptr, line_size, buffer_size);
|
465
479
|
|
466
480
|
yyjson_read_err error;
|
467
|
-
auto doc = JSONCommon::ReadDocumentUnsafe(
|
481
|
+
auto doc = JSONCommon::ReadDocumentUnsafe(buffer_ptr, line_size, JSONCommon::READ_FLAG, alc, &error);
|
468
482
|
if (error.code == YYJSON_READ_SUCCESS) { // We successfully read the line
|
469
483
|
if (yyjson_is_arr(doc->root) && line_size == buffer_size) {
|
470
484
|
// It's just one array, let's actually assume ARRAY, not NEWLINE_DELIMITED
|
@@ -500,8 +514,8 @@ static pair<JSONFormat, JSONRecordType> DetectFormatAndRecordType(const char *co
|
|
500
514
|
|
501
515
|
// It's definitely an ARRAY, but now we have to figure out if there's more than one top-level array
|
502
516
|
yyjson_read_err error;
|
503
|
-
auto doc =
|
504
|
-
|
517
|
+
auto doc =
|
518
|
+
JSONCommon::ReadDocumentUnsafe(buffer_ptr + buffer_offset, remaining, JSONCommon::READ_STOP_FLAG, alc, &error);
|
505
519
|
if (error.code == YYJSON_READ_SUCCESS) {
|
506
520
|
D_ASSERT(yyjson_is_arr(doc->root));
|
507
521
|
|
@@ -563,7 +577,7 @@ bool JSONScanLocalState::ReadNextBuffer(JSONScanGlobalState &gstate) {
|
|
563
577
|
} else {
|
564
578
|
buffer = gstate.allocator.Allocate(gstate.buffer_capacity);
|
565
579
|
}
|
566
|
-
buffer_ptr = (
|
580
|
+
buffer_ptr = char_ptr_cast(buffer.get());
|
567
581
|
|
568
582
|
idx_t buffer_index;
|
569
583
|
while (true) {
|
@@ -573,7 +587,7 @@ bool JSONScanLocalState::ReadNextBuffer(JSONScanGlobalState &gstate) {
|
|
573
587
|
if (is_last && gstate.bind_data.type != JSONScanType::SAMPLE) {
|
574
588
|
current_reader->CloseJSONFile();
|
575
589
|
}
|
576
|
-
if (
|
590
|
+
if (IsParallel(gstate)) {
|
577
591
|
// If this threads' current reader is still the one at gstate.file_index,
|
578
592
|
// this thread can end the parallel scan
|
579
593
|
lock_guard<mutex> guard(gstate.lock);
|
@@ -599,7 +613,7 @@ bool JSONScanLocalState::ReadNextBuffer(JSONScanGlobalState &gstate) {
|
|
599
613
|
current_reader = gstate.json_readers[gstate.file_index].get();
|
600
614
|
if (current_reader->IsOpen()) {
|
601
615
|
// Can only be open from auto detection, so these should be known
|
602
|
-
if (!
|
616
|
+
if (!IsParallel(gstate)) {
|
603
617
|
batch_index = gstate.batch_index++;
|
604
618
|
gstate.file_index++;
|
605
619
|
}
|
@@ -609,15 +623,15 @@ bool JSONScanLocalState::ReadNextBuffer(JSONScanGlobalState &gstate) {
|
|
609
623
|
current_reader->OpenJSONFile();
|
610
624
|
batch_index = gstate.batch_index++;
|
611
625
|
if (current_reader->GetFormat() != JSONFormat::AUTO_DETECT) {
|
612
|
-
if (!
|
626
|
+
if (!IsParallel(gstate)) {
|
613
627
|
gstate.file_index++;
|
614
628
|
}
|
615
629
|
continue;
|
616
630
|
}
|
617
631
|
|
618
|
-
// If we have
|
632
|
+
// If we have less files than threads, we auto-detect within the lock,
|
619
633
|
// so other threads may join a parallel NDJSON scan
|
620
|
-
if (gstate.json_readers.size() <
|
634
|
+
if (gstate.json_readers.size() < gstate.system_threads) {
|
621
635
|
if (ReadAndAutoDetect(gstate, buffer_index, false)) {
|
622
636
|
continue;
|
623
637
|
}
|
@@ -637,7 +651,7 @@ bool JSONScanLocalState::ReadNextBuffer(JSONScanGlobalState &gstate) {
|
|
637
651
|
D_ASSERT(buffer_size != 0); // We should have read something if we got here
|
638
652
|
|
639
653
|
idx_t readers = 1;
|
640
|
-
if (current_reader->
|
654
|
+
if (current_reader->GetFormat() == JSONFormat::NEWLINE_DELIMITED) {
|
641
655
|
readers = is_last ? 1 : 2;
|
642
656
|
}
|
643
657
|
|
@@ -650,7 +664,7 @@ bool JSONScanLocalState::ReadNextBuffer(JSONScanGlobalState &gstate) {
|
|
650
664
|
lines_or_objects_in_buffer = 0;
|
651
665
|
|
652
666
|
// YYJSON needs this
|
653
|
-
memset(
|
667
|
+
memset(buffer_ptr + buffer_size, 0, YYJSON_PADDING_SIZE);
|
654
668
|
|
655
669
|
return true;
|
656
670
|
}
|
@@ -680,7 +694,7 @@ bool JSONScanLocalState::ReadAndAutoDetect(JSONScanGlobalState &gstate, idx_t &b
|
|
680
694
|
throw InvalidInputException("Expected file \"%s\" to contain records, detected non-record JSON instead.",
|
681
695
|
current_reader->GetFileName());
|
682
696
|
}
|
683
|
-
if (!already_incremented_file_idx && !
|
697
|
+
if (!already_incremented_file_idx && !IsParallel(gstate)) {
|
684
698
|
gstate.file_index++;
|
685
699
|
}
|
686
700
|
return false;
|
@@ -739,13 +753,14 @@ void JSONScanLocalState::ReadNextBufferNoSeek(JSONScanGlobalState &gstate, idx_t
|
|
739
753
|
lock_guard<mutex> reader_guard(current_reader->lock);
|
740
754
|
buffer_index = current_reader->GetBufferIndex();
|
741
755
|
|
742
|
-
if (current_reader->IsOpen()) {
|
756
|
+
if (current_reader->IsOpen() && !current_reader->IsDone()) {
|
743
757
|
read_size = current_reader->GetFileHandle().Read(buffer_ptr + prev_buffer_remainder, request_size,
|
744
758
|
gstate.bind_data.type == JSONScanType::SAMPLE);
|
759
|
+
is_last = read_size < request_size;
|
745
760
|
} else {
|
746
761
|
read_size = 0;
|
762
|
+
is_last = false;
|
747
763
|
}
|
748
|
-
is_last = read_size < request_size;
|
749
764
|
|
750
765
|
if (!gstate.bind_data.ignore_errors && read_size == 0 && prev_buffer_remainder != 0) {
|
751
766
|
ThrowInvalidAtEndError();
|
@@ -796,13 +811,13 @@ void JSONScanLocalState::ReconstructFirstObject(JSONScanGlobalState &gstate) {
|
|
796
811
|
D_ASSERT(current_reader->GetFormat() == JSONFormat::NEWLINE_DELIMITED);
|
797
812
|
|
798
813
|
// Spinlock until the previous batch index has also read its buffer
|
799
|
-
JSONBufferHandle
|
814
|
+
optional_ptr<JSONBufferHandle> previous_buffer_handle;
|
800
815
|
while (!previous_buffer_handle) {
|
801
816
|
previous_buffer_handle = current_reader->GetBuffer(current_buffer_handle->buffer_index - 1);
|
802
817
|
}
|
803
818
|
|
804
819
|
// First we find the newline in the previous block
|
805
|
-
auto prev_buffer_ptr = (
|
820
|
+
auto prev_buffer_ptr = char_ptr_cast(previous_buffer_handle->buffer.get()) + previous_buffer_handle->buffer_size;
|
806
821
|
auto part1_ptr = PreviousNewline(prev_buffer_ptr);
|
807
822
|
auto part1_size = prev_buffer_ptr - part1_ptr;
|
808
823
|
|
@@ -825,7 +840,7 @@ void JSONScanLocalState::ReconstructFirstObject(JSONScanGlobalState &gstate) {
|
|
825
840
|
|
826
841
|
// And copy the remainder of the line to the reconstruct buffer
|
827
842
|
memcpy(reconstruct_ptr + part1_size, buffer_ptr, part2_size);
|
828
|
-
memset(
|
843
|
+
memset(reconstruct_ptr + line_size, 0, YYJSON_PADDING_SIZE);
|
829
844
|
buffer_offset += part2_size;
|
830
845
|
|
831
846
|
// We copied the object, so we are no longer reading the previous buffer
|
@@ -833,7 +848,7 @@ void JSONScanLocalState::ReconstructFirstObject(JSONScanGlobalState &gstate) {
|
|
833
848
|
current_reader->RemoveBuffer(current_buffer_handle->buffer_index - 1);
|
834
849
|
}
|
835
850
|
|
836
|
-
ParseJSON((
|
851
|
+
ParseJSON(char_ptr_cast(reconstruct_ptr), line_size, line_size);
|
837
852
|
}
|
838
853
|
|
839
854
|
void JSONScanLocalState::ParseNextChunk() {
|
@@ -867,7 +882,7 @@ void JSONScanLocalState::ParseNextChunk() {
|
|
867
882
|
}
|
868
883
|
|
869
884
|
idx_t json_size = json_end - json_start;
|
870
|
-
ParseJSON(
|
885
|
+
ParseJSON(json_start, json_size, remaining);
|
871
886
|
buffer_offset += json_size;
|
872
887
|
|
873
888
|
if (format == JSONFormat::ARRAY) {
|
@@ -947,9 +962,10 @@ void JSONScan::Serialize(FieldWriter &writer, const FunctionData *bind_data_p, c
|
|
947
962
|
bind_data.Serialize(writer);
|
948
963
|
}
|
949
964
|
|
950
|
-
unique_ptr<FunctionData> JSONScan::Deserialize(
|
965
|
+
unique_ptr<FunctionData> JSONScan::Deserialize(PlanDeserializationState &state, FieldReader &reader,
|
966
|
+
TableFunction &function) {
|
951
967
|
auto result = make_uniq<JSONScanData>();
|
952
|
-
result->Deserialize(context, reader);
|
968
|
+
result->Deserialize(state.context, reader);
|
953
969
|
return std::move(result);
|
954
970
|
}
|
955
971
|
|
@@ -95,7 +95,11 @@ const uint64_t ParquetDecodeUtils::BITPACK_MASKS[] = {0,
|
|
95
95
|
576460752303423487,
|
96
96
|
1152921504606846975,
|
97
97
|
2305843009213693951,
|
98
|
-
4611686018427387903
|
98
|
+
4611686018427387903,
|
99
|
+
9223372036854775807,
|
100
|
+
18446744073709551615ULL};
|
101
|
+
|
102
|
+
const uint64_t ParquetDecodeUtils::BITPACK_MASKS_SIZE = sizeof(ParquetDecodeUtils::BITPACK_MASKS) / sizeof(uint64_t);
|
99
103
|
|
100
104
|
const uint8_t ParquetDecodeUtils::BITPACK_DLEN = 8;
|
101
105
|
|
@@ -12,10 +12,16 @@ public:
|
|
12
12
|
}
|
13
13
|
|
14
14
|
static const uint64_t BITPACK_MASKS[];
|
15
|
+
static const uint64_t BITPACK_MASKS_SIZE;
|
15
16
|
static const uint8_t BITPACK_DLEN;
|
16
17
|
|
17
18
|
template <typename T>
|
18
19
|
static uint32_t BitUnpack(ByteBuffer &buffer, uint8_t &bitpack_pos, T *dest, uint32_t count, uint8_t width) {
|
20
|
+
if (width >= ParquetDecodeUtils::BITPACK_MASKS_SIZE) {
|
21
|
+
throw InvalidInputException("The width (%d) of the bitpacked data exceeds the supported max width (%d), "
|
22
|
+
"the file might be corrupted.",
|
23
|
+
width, ParquetDecodeUtils::BITPACK_MASKS_SIZE);
|
24
|
+
}
|
19
25
|
auto mask = BITPACK_MASKS[width];
|
20
26
|
|
21
27
|
for (uint32_t i = 0; i < count; i++) {
|
@@ -411,8 +411,9 @@ public:
|
|
411
411
|
bind_data.parquet_options.Serialize(writer);
|
412
412
|
}
|
413
413
|
|
414
|
-
static unique_ptr<FunctionData> ParquetScanDeserialize(
|
414
|
+
static unique_ptr<FunctionData> ParquetScanDeserialize(PlanDeserializationState &state, FieldReader &reader,
|
415
415
|
TableFunction &function) {
|
416
|
+
auto &context = state.context;
|
416
417
|
auto files = reader.ReadRequiredList<string>();
|
417
418
|
auto types = reader.ReadRequiredSerializableList<LogicalType, LogicalType>();
|
418
419
|
auto names = reader.ReadRequiredList<string>();
|
@@ -665,6 +666,28 @@ unique_ptr<LocalFunctionData> ParquetWriteInitializeLocal(ExecutionContext &cont
|
|
665
666
|
return make_uniq<ParquetWriteLocalState>(context.client, bind_data.sql_types);
|
666
667
|
}
|
667
668
|
|
669
|
+
// LCOV_EXCL_START
|
670
|
+
static void ParquetCopySerialize(FieldWriter &writer, const FunctionData &bind_data_p, const CopyFunction &function) {
|
671
|
+
auto &bind_data = bind_data_p.Cast<ParquetWriteBindData>();
|
672
|
+
writer.WriteRegularSerializableList<LogicalType>(bind_data.sql_types);
|
673
|
+
writer.WriteList<string>(bind_data.column_names);
|
674
|
+
writer.WriteField<duckdb_parquet::format::CompressionCodec::type>(bind_data.codec);
|
675
|
+
writer.WriteField<idx_t>(bind_data.row_group_size);
|
676
|
+
}
|
677
|
+
|
678
|
+
static unique_ptr<FunctionData> ParquetCopyDeserialize(ClientContext &context, FieldReader &reader,
|
679
|
+
CopyFunction &function) {
|
680
|
+
unique_ptr<ParquetWriteBindData> data = make_uniq<ParquetWriteBindData>();
|
681
|
+
|
682
|
+
data->sql_types = reader.ReadRequiredSerializableList<LogicalType, LogicalType>();
|
683
|
+
data->column_names = reader.ReadRequiredList<string>();
|
684
|
+
data->codec = reader.ReadRequired<duckdb_parquet::format::CompressionCodec::type>();
|
685
|
+
data->row_group_size = reader.ReadRequired<idx_t>();
|
686
|
+
|
687
|
+
return std::move(data);
|
688
|
+
}
|
689
|
+
// LCOV_EXCL_STOP
|
690
|
+
|
668
691
|
//===--------------------------------------------------------------------===//
|
669
692
|
// Execution Mode
|
670
693
|
//===--------------------------------------------------------------------===//
|
@@ -764,6 +787,8 @@ void ParquetExtension::Load(DuckDB &db) {
|
|
764
787
|
function.prepare_batch = ParquetWritePrepareBatch;
|
765
788
|
function.flush_batch = ParquetWriteFlushBatch;
|
766
789
|
function.desired_batch_size = ParquetWriteDesiredBatchSize;
|
790
|
+
function.serialize = ParquetCopySerialize;
|
791
|
+
function.deserialize = ParquetCopyDeserialize;
|
767
792
|
|
768
793
|
function.extension = "parquet";
|
769
794
|
ExtensionUtil::RegisterFunction(db_instance, function);
|
@@ -674,31 +674,19 @@ vector<reference<SchemaCatalogEntry>> Catalog::GetSchemas(ClientContext &context
|
|
674
674
|
return schemas;
|
675
675
|
}
|
676
676
|
|
677
|
-
bool Catalog::TypeExists(ClientContext &context, const string &catalog_name, const string &schema, const string &name) {
|
678
|
-
optional_ptr<CatalogEntry> entry;
|
679
|
-
entry = GetEntry(context, CatalogType::TYPE_ENTRY, catalog_name, schema, name, OnEntryNotFound::RETURN_NULL);
|
680
|
-
if (!entry) {
|
681
|
-
// look in the system catalog
|
682
|
-
entry = GetEntry(context, CatalogType::TYPE_ENTRY, SYSTEM_CATALOG, schema, name, OnEntryNotFound::RETURN_NULL);
|
683
|
-
if (!entry) {
|
684
|
-
return false;
|
685
|
-
}
|
686
|
-
}
|
687
|
-
return true;
|
688
|
-
}
|
689
|
-
|
690
677
|
vector<reference<SchemaCatalogEntry>> Catalog::GetSchemas(ClientContext &context, const string &catalog_name) {
|
691
678
|
vector<reference<Catalog>> catalogs;
|
692
679
|
if (IsInvalidCatalog(catalog_name)) {
|
693
|
-
|
680
|
+
reference_set_t<Catalog> inserted_catalogs;
|
694
681
|
|
695
682
|
auto &search_path = *context.client_data->catalog_search_path;
|
696
683
|
for (auto &entry : search_path.Get()) {
|
697
|
-
|
684
|
+
auto &catalog = Catalog::GetCatalog(context, entry.catalog);
|
685
|
+
if (inserted_catalogs.find(catalog) != inserted_catalogs.end()) {
|
698
686
|
continue;
|
699
687
|
}
|
700
|
-
|
701
|
-
catalogs.push_back(
|
688
|
+
inserted_catalogs.insert(catalog);
|
689
|
+
catalogs.push_back(catalog);
|
702
690
|
}
|
703
691
|
} else {
|
704
692
|
catalogs.push_back(Catalog::GetCatalog(context, catalog_name));
|
@@ -16,6 +16,9 @@
|
|
16
16
|
#include "duckdb/parser/constraints/list.hpp"
|
17
17
|
#include "duckdb/function/table/table_scan.hpp"
|
18
18
|
#include "duckdb/storage/table_storage_info.hpp"
|
19
|
+
#include "duckdb/planner/operator/logical_get.hpp"
|
20
|
+
#include "duckdb/planner/operator/logical_projection.hpp"
|
21
|
+
#include "duckdb/planner/operator/logical_update.hpp"
|
19
22
|
|
20
23
|
namespace duckdb {
|
21
24
|
|
@@ -714,10 +717,13 @@ TableFunction DuckTableEntry::GetScanFunction(ClientContext &context, unique_ptr
|
|
714
717
|
return TableScanFunction::GetFunction();
|
715
718
|
}
|
716
719
|
|
720
|
+
vector<ColumnSegmentInfo> DuckTableEntry::GetColumnSegmentInfo() {
|
721
|
+
return storage->GetColumnSegmentInfo();
|
722
|
+
}
|
723
|
+
|
717
724
|
TableStorageInfo DuckTableEntry::GetStorageInfo(ClientContext &context) {
|
718
725
|
TableStorageInfo result;
|
719
726
|
result.cardinality = storage->info->cardinality.load();
|
720
|
-
storage->GetStorageInfo(result);
|
721
727
|
storage->info->indexes.Scan([&](Index &index) {
|
722
728
|
IndexInfo info;
|
723
729
|
info.is_primary = index.IsPrimary();
|
@@ -9,6 +9,11 @@
|
|
9
9
|
#include "duckdb/main/database.hpp"
|
10
10
|
#include "duckdb/parser/constraints/list.hpp"
|
11
11
|
#include "duckdb/parser/parsed_data/create_table_info.hpp"
|
12
|
+
#include "duckdb/storage/table_storage_info.hpp"
|
13
|
+
#include "duckdb/planner/operator/logical_update.hpp"
|
14
|
+
#include "duckdb/planner/operator/logical_get.hpp"
|
15
|
+
#include "duckdb/planner/constraints/bound_check_constraint.hpp"
|
16
|
+
#include "duckdb/planner/operator/logical_projection.hpp"
|
12
17
|
|
13
18
|
#include <sstream>
|
14
19
|
|
@@ -214,6 +219,122 @@ DataTable &TableCatalogEntry::GetStorage() {
|
|
214
219
|
const vector<unique_ptr<BoundConstraint>> &TableCatalogEntry::GetBoundConstraints() {
|
215
220
|
throw InternalException("Calling GetBoundConstraints on a TableCatalogEntry that is not a DuckTableEntry");
|
216
221
|
}
|
222
|
+
|
217
223
|
// LCOV_EXCL_STOP
|
218
224
|
|
225
|
+
static void BindExtraColumns(TableCatalogEntry &table, LogicalGet &get, LogicalProjection &proj, LogicalUpdate &update,
|
226
|
+
physical_index_set_t &bound_columns) {
|
227
|
+
if (bound_columns.size() <= 1) {
|
228
|
+
return;
|
229
|
+
}
|
230
|
+
idx_t found_column_count = 0;
|
231
|
+
physical_index_set_t found_columns;
|
232
|
+
for (idx_t i = 0; i < update.columns.size(); i++) {
|
233
|
+
if (bound_columns.find(update.columns[i]) != bound_columns.end()) {
|
234
|
+
// this column is referenced in the CHECK constraint
|
235
|
+
found_column_count++;
|
236
|
+
found_columns.insert(update.columns[i]);
|
237
|
+
}
|
238
|
+
}
|
239
|
+
if (found_column_count > 0 && found_column_count != bound_columns.size()) {
|
240
|
+
// columns in this CHECK constraint were referenced, but not all were part of the UPDATE
|
241
|
+
// add them to the scan and update set
|
242
|
+
for (auto &check_column_id : bound_columns) {
|
243
|
+
if (found_columns.find(check_column_id) != found_columns.end()) {
|
244
|
+
// column is already projected
|
245
|
+
continue;
|
246
|
+
}
|
247
|
+
// column is not projected yet: project it by adding the clause "i=i" to the set of updated columns
|
248
|
+
auto &column = table.GetColumns().GetColumn(check_column_id);
|
249
|
+
update.expressions.push_back(make_uniq<BoundColumnRefExpression>(
|
250
|
+
column.Type(), ColumnBinding(proj.table_index, proj.expressions.size())));
|
251
|
+
proj.expressions.push_back(make_uniq<BoundColumnRefExpression>(
|
252
|
+
column.Type(), ColumnBinding(get.table_index, get.column_ids.size())));
|
253
|
+
get.column_ids.push_back(check_column_id.index);
|
254
|
+
update.columns.push_back(check_column_id);
|
255
|
+
}
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
static bool TypeSupportsRegularUpdate(const LogicalType &type) {
|
260
|
+
switch (type.id()) {
|
261
|
+
case LogicalTypeId::LIST:
|
262
|
+
case LogicalTypeId::MAP:
|
263
|
+
case LogicalTypeId::UNION:
|
264
|
+
// lists and maps and unions don't support updates directly
|
265
|
+
return false;
|
266
|
+
case LogicalTypeId::STRUCT: {
|
267
|
+
auto &child_types = StructType::GetChildTypes(type);
|
268
|
+
for (auto &entry : child_types) {
|
269
|
+
if (!TypeSupportsRegularUpdate(entry.second)) {
|
270
|
+
return false;
|
271
|
+
}
|
272
|
+
}
|
273
|
+
return true;
|
274
|
+
}
|
275
|
+
default:
|
276
|
+
return true;
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
vector<ColumnSegmentInfo> TableCatalogEntry::GetColumnSegmentInfo() {
|
281
|
+
return {};
|
282
|
+
}
|
283
|
+
|
284
|
+
void TableCatalogEntry::BindUpdateConstraints(LogicalGet &get, LogicalProjection &proj, LogicalUpdate &update,
|
285
|
+
ClientContext &context) {
|
286
|
+
// check the constraints and indexes of the table to see if we need to project any additional columns
|
287
|
+
// we do this for indexes with multiple columns and CHECK constraints in the UPDATE clause
|
288
|
+
// suppose we have a constraint CHECK(i + j < 10); now we need both i and j to check the constraint
|
289
|
+
// if we are only updating one of the two columns we add the other one to the UPDATE set
|
290
|
+
// with a "useless" update (i.e. i=i) so we can verify that the CHECK constraint is not violated
|
291
|
+
for (auto &constraint : GetBoundConstraints()) {
|
292
|
+
if (constraint->type == ConstraintType::CHECK) {
|
293
|
+
auto &check = constraint->Cast<BoundCheckConstraint>();
|
294
|
+
// check constraint! check if we need to add any extra columns to the UPDATE clause
|
295
|
+
BindExtraColumns(*this, get, proj, update, check.bound_columns);
|
296
|
+
}
|
297
|
+
}
|
298
|
+
if (update.return_chunk) {
|
299
|
+
physical_index_set_t all_columns;
|
300
|
+
for (auto &column : GetColumns().Physical()) {
|
301
|
+
all_columns.insert(column.Physical());
|
302
|
+
}
|
303
|
+
BindExtraColumns(*this, get, proj, update, all_columns);
|
304
|
+
}
|
305
|
+
// for index updates we always turn any update into an insert and a delete
|
306
|
+
// we thus need all the columns to be available, hence we check if the update touches any index columns
|
307
|
+
// If the returning keyword is used, we need access to the whole row in case the user requests it.
|
308
|
+
// Therefore switch the update to a delete and insert.
|
309
|
+
update.update_is_del_and_insert = false;
|
310
|
+
TableStorageInfo table_storage_info = GetStorageInfo(context);
|
311
|
+
for (auto index : table_storage_info.index_info) {
|
312
|
+
for (auto &column : update.columns) {
|
313
|
+
if (index.column_set.find(column.index) != index.column_set.end()) {
|
314
|
+
update.update_is_del_and_insert = true;
|
315
|
+
break;
|
316
|
+
}
|
317
|
+
}
|
318
|
+
};
|
319
|
+
|
320
|
+
// we also convert any updates on LIST columns into delete + insert
|
321
|
+
for (auto &col_index : update.columns) {
|
322
|
+
auto &column = GetColumns().GetColumn(col_index);
|
323
|
+
if (!TypeSupportsRegularUpdate(column.Type())) {
|
324
|
+
update.update_is_del_and_insert = true;
|
325
|
+
break;
|
326
|
+
}
|
327
|
+
}
|
328
|
+
|
329
|
+
if (update.update_is_del_and_insert) {
|
330
|
+
// the update updates a column required by an index or requires returning the updated rows,
|
331
|
+
// push projections for all columns
|
332
|
+
physical_index_set_t all_columns;
|
333
|
+
for (auto &column : GetColumns().Physical()) {
|
334
|
+
all_columns.insert(column.Physical());
|
335
|
+
}
|
336
|
+
BindExtraColumns(*this, get, proj, update, all_columns);
|
337
|
+
}
|
338
|
+
}
|
339
|
+
|
219
340
|
} // namespace duckdb
|
@@ -5,6 +5,7 @@
|
|
5
5
|
#include "duckdb/common/string_util.hpp"
|
6
6
|
#include "duckdb/main/client_context.hpp"
|
7
7
|
#include "duckdb/catalog/catalog.hpp"
|
8
|
+
#include "duckdb/main/database_manager.hpp"
|
8
9
|
|
9
10
|
namespace duckdb {
|
10
11
|
|
@@ -126,37 +127,57 @@ void CatalogSearchPath::Reset() {
|
|
126
127
|
SetPaths(empty);
|
127
128
|
}
|
128
129
|
|
129
|
-
|
130
|
-
|
131
|
-
|
130
|
+
string CatalogSearchPath::GetSetName(CatalogSetPathType set_type) {
|
131
|
+
switch (set_type) {
|
132
|
+
case CatalogSetPathType::SET_SCHEMA:
|
133
|
+
return "SET schema";
|
134
|
+
case CatalogSetPathType::SET_SCHEMAS:
|
135
|
+
return "SET search_path";
|
136
|
+
default:
|
137
|
+
throw InternalException("Unrecognized CatalogSetPathType");
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
141
|
+
void CatalogSearchPath::Set(vector<CatalogSearchEntry> new_paths, CatalogSetPathType set_type) {
|
142
|
+
if (set_type != CatalogSetPathType::SET_SCHEMAS && new_paths.size() != 1) {
|
143
|
+
throw CatalogException("%s can set only 1 schema. This has %d", GetSetName(set_type), new_paths.size());
|
132
144
|
}
|
133
145
|
for (auto &path : new_paths) {
|
134
|
-
|
146
|
+
auto schema_entry = Catalog::GetSchema(context, path.catalog, path.schema, OnEntryNotFound::RETURN_NULL);
|
147
|
+
if (schema_entry) {
|
148
|
+
// we are setting a schema - update the catalog and schema
|
135
149
|
if (path.catalog.empty()) {
|
136
|
-
|
137
|
-
|
150
|
+
path.catalog = GetDefault().catalog;
|
151
|
+
}
|
152
|
+
continue;
|
153
|
+
}
|
154
|
+
// only schema supplied - check if this is a catalog instead
|
155
|
+
if (path.catalog.empty()) {
|
156
|
+
auto catalog = Catalog::GetCatalogEntry(context, path.schema);
|
157
|
+
if (catalog) {
|
158
|
+
auto schema = catalog->GetSchema(context, DEFAULT_SCHEMA, OnEntryNotFound::RETURN_NULL);
|
138
159
|
if (schema) {
|
139
160
|
path.catalog = std::move(path.schema);
|
140
161
|
path.schema = schema->name;
|
141
162
|
continue;
|
142
163
|
}
|
143
164
|
}
|
144
|
-
throw CatalogException("SET %s: No catalog + schema named %s found.",
|
145
|
-
is_set_schema ? "schema" : "search_path", path.ToString());
|
146
165
|
}
|
166
|
+
throw CatalogException("%s: No catalog + schema named \"%s\" found.", GetSetName(set_type), path.ToString());
|
147
167
|
}
|
148
|
-
if (
|
168
|
+
if (set_type == CatalogSetPathType::SET_SCHEMA) {
|
149
169
|
if (new_paths[0].catalog == TEMP_CATALOG || new_paths[0].catalog == SYSTEM_CATALOG) {
|
150
|
-
throw CatalogException("
|
170
|
+
throw CatalogException("%s cannot be set to internal schema \"%s\"", GetSetName(set_type),
|
171
|
+
new_paths[0].catalog);
|
151
172
|
}
|
152
173
|
}
|
153
174
|
this->set_paths = std::move(new_paths);
|
154
175
|
SetPaths(set_paths);
|
155
176
|
}
|
156
177
|
|
157
|
-
void CatalogSearchPath::Set(CatalogSearchEntry new_value,
|
178
|
+
void CatalogSearchPath::Set(CatalogSearchEntry new_value, CatalogSetPathType set_type) {
|
158
179
|
vector<CatalogSearchEntry> new_paths {std::move(new_value)};
|
159
|
-
Set(std::move(new_paths),
|
180
|
+
Set(std::move(new_paths), set_type);
|
160
181
|
}
|
161
182
|
|
162
183
|
const vector<CatalogSearchEntry> &CatalogSearchPath::Get() {
|
@@ -225,4 +246,20 @@ void CatalogSearchPath::SetPaths(vector<CatalogSearchEntry> new_paths) {
|
|
225
246
|
paths.emplace_back(SYSTEM_CATALOG, "pg_catalog");
|
226
247
|
}
|
227
248
|
|
249
|
+
bool CatalogSearchPath::SchemaInSearchPath(ClientContext &context, const string &catalog_name,
|
250
|
+
const string &schema_name) {
|
251
|
+
for (auto &path : paths) {
|
252
|
+
if (path.schema != schema_name) {
|
253
|
+
continue;
|
254
|
+
}
|
255
|
+
if (path.catalog == catalog_name) {
|
256
|
+
return true;
|
257
|
+
}
|
258
|
+
if (IsInvalidCatalog(path.catalog) && catalog_name == DatabaseManager::GetDefaultDatabase(context)) {
|
259
|
+
return true;
|
260
|
+
}
|
261
|
+
}
|
262
|
+
return false;
|
263
|
+
}
|
264
|
+
|
228
265
|
} // namespace duckdb
|