duckdb 0.8.2-dev33.0 → 0.8.2-dev3300.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/README.md +7 -0
- package/binding.gyp +25 -13
- package/binding.gyp.in +1 -1
- package/configure.py +8 -3
- package/duckdb_extension_config.cmake +10 -0
- package/package.json +1 -1
- package/src/duckdb/extension/icu/icu-dateadd.cpp +2 -2
- package/src/duckdb/extension/icu/icu-datefunc.cpp +10 -1
- package/src/duckdb/extension/icu/icu-datepart.cpp +162 -41
- package/src/duckdb/extension/icu/icu-datesub.cpp +3 -2
- package/src/duckdb/extension/icu/icu-datetrunc.cpp +2 -1
- package/src/duckdb/extension/icu/icu-list-range.cpp +1 -1
- package/src/duckdb/extension/icu/icu-makedate.cpp +19 -6
- package/src/duckdb/extension/icu/icu-strptime.cpp +5 -24
- package/src/duckdb/extension/icu/icu-table-range.cpp +5 -5
- package/src/duckdb/extension/icu/icu-timebucket.cpp +16 -16
- package/src/duckdb/extension/icu/icu-timezone.cpp +8 -8
- package/src/duckdb/extension/icu/icu_extension.cpp +5 -7
- package/src/duckdb/extension/json/buffered_json_reader.cpp +2 -0
- package/src/duckdb/extension/json/include/buffered_json_reader.hpp +5 -19
- package/src/duckdb/extension/json/include/json_common.hpp +47 -231
- package/src/duckdb/extension/json/include/json_deserializer.hpp +1 -1
- package/src/duckdb/extension/json/include/json_enums.hpp +60 -0
- package/src/duckdb/extension/json/include/json_executors.hpp +49 -13
- package/src/duckdb/extension/json/include/json_functions.hpp +2 -1
- package/src/duckdb/extension/json/include/json_scan.hpp +14 -10
- package/src/duckdb/extension/json/include/json_serializer.hpp +1 -1
- package/src/duckdb/extension/json/include/json_transform.hpp +3 -0
- package/src/duckdb/extension/json/json_common.cpp +272 -40
- package/src/duckdb/extension/json/json_deserializer.cpp +16 -14
- package/src/duckdb/extension/json/json_enums.cpp +105 -0
- package/src/duckdb/extension/json/json_functions/json_create.cpp +21 -2
- package/src/duckdb/extension/json/json_functions/json_structure.cpp +1 -1
- package/src/duckdb/extension/json/json_functions/json_transform.cpp +93 -38
- package/src/duckdb/extension/json/json_functions/json_type.cpp +1 -1
- package/src/duckdb/extension/json/json_functions.cpp +26 -25
- package/src/duckdb/extension/json/json_scan.cpp +47 -6
- package/src/duckdb/extension/json/json_serializer.cpp +11 -11
- package/src/duckdb/extension/json/serialize_json.cpp +92 -0
- package/src/duckdb/extension/parquet/column_reader.cpp +37 -25
- package/src/duckdb/extension/parquet/column_writer.cpp +77 -61
- package/src/duckdb/extension/parquet/include/cast_column_reader.hpp +2 -2
- package/src/duckdb/extension/parquet/include/column_reader.hpp +14 -16
- package/src/duckdb/extension/parquet/include/column_writer.hpp +9 -7
- package/src/duckdb/extension/parquet/include/list_column_reader.hpp +2 -2
- package/src/duckdb/extension/parquet/include/parquet_dbp_decoder.hpp +3 -3
- package/src/duckdb/extension/parquet/include/parquet_decimal_utils.hpp +3 -3
- package/src/duckdb/extension/parquet/include/parquet_file_metadata_cache.hpp +2 -2
- package/src/duckdb/extension/parquet/include/parquet_reader.hpp +4 -0
- package/src/duckdb/extension/parquet/include/parquet_statistics.hpp +2 -2
- package/src/duckdb/extension/parquet/include/parquet_support.hpp +9 -11
- package/src/duckdb/extension/parquet/include/parquet_timestamp.hpp +1 -0
- package/src/duckdb/extension/parquet/include/parquet_writer.hpp +28 -5
- package/src/duckdb/extension/parquet/include/string_column_reader.hpp +1 -1
- package/src/duckdb/extension/parquet/include/struct_column_reader.hpp +2 -3
- package/src/duckdb/extension/parquet/include/zstd_file_system.hpp +2 -2
- package/src/duckdb/extension/parquet/parquet_extension.cpp +258 -40
- package/src/duckdb/extension/parquet/parquet_reader.cpp +10 -10
- package/src/duckdb/extension/parquet/parquet_statistics.cpp +25 -8
- package/src/duckdb/extension/parquet/parquet_timestamp.cpp +6 -0
- package/src/duckdb/extension/parquet/parquet_writer.cpp +149 -31
- package/src/duckdb/extension/parquet/serialize_parquet.cpp +26 -0
- package/src/duckdb/extension/parquet/zstd_file_system.cpp +2 -2
- package/src/duckdb/src/catalog/catalog.cpp +3 -7
- package/src/duckdb/src/catalog/catalog_entry/duck_table_entry.cpp +8 -11
- package/src/duckdb/src/catalog/catalog_entry/index_catalog_entry.cpp +17 -41
- package/src/duckdb/src/catalog/catalog_entry/macro_catalog_entry.cpp +2 -10
- package/src/duckdb/src/catalog/catalog_entry/schema_catalog_entry.cpp +4 -14
- package/src/duckdb/src/catalog/catalog_entry/sequence_catalog_entry.cpp +11 -28
- package/src/duckdb/src/catalog/catalog_entry/table_catalog_entry.cpp +11 -42
- package/src/duckdb/src/catalog/catalog_entry/type_catalog_entry.cpp +7 -26
- package/src/duckdb/src/catalog/catalog_entry/view_catalog_entry.cpp +11 -27
- package/src/duckdb/src/catalog/catalog_entry.cpp +25 -1
- package/src/duckdb/src/catalog/catalog_search_path.cpp +5 -4
- package/src/duckdb/src/catalog/catalog_set.cpp +0 -63
- package/src/duckdb/src/catalog/default/default_functions.cpp +21 -0
- package/src/duckdb/src/catalog/dependency_manager.cpp +0 -36
- package/src/duckdb/src/common/adbc/adbc.cpp +541 -171
- package/src/duckdb/src/common/adbc/driver_manager.cpp +92 -39
- package/src/duckdb/src/common/adbc/nanoarrow/allocator.cpp +57 -0
- package/src/duckdb/src/common/adbc/nanoarrow/metadata.cpp +121 -0
- package/src/duckdb/src/common/adbc/nanoarrow/schema.cpp +474 -0
- package/src/duckdb/src/common/adbc/nanoarrow/single_batch_array_stream.cpp +84 -0
- package/src/duckdb/src/common/allocator.cpp +14 -2
- package/src/duckdb/src/common/arrow/appender/bool_data.cpp +44 -0
- package/src/duckdb/src/common/arrow/appender/list_data.cpp +78 -0
- package/src/duckdb/src/common/arrow/appender/map_data.cpp +86 -0
- package/src/duckdb/src/common/arrow/appender/struct_data.cpp +45 -0
- package/src/duckdb/src/common/arrow/appender/union_data.cpp +70 -0
- package/src/duckdb/src/common/arrow/arrow_appender.cpp +95 -666
- package/src/duckdb/src/common/arrow/arrow_converter.cpp +65 -37
- package/src/duckdb/src/common/arrow/arrow_wrapper.cpp +37 -42
- package/src/duckdb/src/common/assert.cpp +3 -0
- package/src/duckdb/src/common/constants.cpp +2 -1
- package/src/duckdb/src/common/enum_util.cpp +4838 -4429
- package/src/duckdb/src/common/enums/date_part_specifier.cpp +2 -0
- package/src/duckdb/src/common/enums/logical_operator_type.cpp +4 -0
- package/src/duckdb/src/common/enums/optimizer_type.cpp +2 -0
- package/src/duckdb/src/common/enums/physical_operator_type.cpp +4 -0
- package/src/duckdb/src/common/exception.cpp +2 -2
- package/src/duckdb/src/common/extra_type_info.cpp +483 -0
- package/src/duckdb/src/common/field_writer.cpp +1 -1
- package/src/duckdb/src/common/file_system.cpp +25 -6
- package/src/duckdb/src/common/filename_pattern.cpp +1 -1
- package/src/duckdb/src/common/gzip_file_system.cpp +7 -12
- package/src/duckdb/src/common/hive_partitioning.cpp +10 -6
- package/src/duckdb/src/common/http_state.cpp +78 -0
- package/src/duckdb/src/common/local_file_system.cpp +36 -28
- package/src/duckdb/src/common/multi_file_reader.cpp +193 -20
- package/src/duckdb/src/common/operator/cast_operators.cpp +92 -1
- package/src/duckdb/src/common/operator/string_cast.cpp +45 -8
- package/src/duckdb/src/common/radix_partitioning.cpp +26 -8
- package/src/duckdb/src/common/re2_regex.cpp +1 -1
- package/src/duckdb/src/common/row_operations/row_external.cpp +1 -1
- package/src/duckdb/src/common/serializer/binary_deserializer.cpp +8 -3
- package/src/duckdb/src/common/serializer/binary_serializer.cpp +14 -9
- package/src/duckdb/src/common/serializer/buffered_file_reader.cpp +0 -9
- package/src/duckdb/src/common/serializer/format_serializer.cpp +15 -0
- package/src/duckdb/src/common/sort/merge_sorter.cpp +9 -16
- package/src/duckdb/src/common/sort/partition_state.cpp +70 -50
- package/src/duckdb/src/common/sort/sort_state.cpp +1 -1
- package/src/duckdb/src/common/sort/sorted_block.cpp +1 -1
- package/src/duckdb/src/common/types/batched_data_collection.cpp +7 -2
- package/src/duckdb/src/common/types/bit.cpp +51 -0
- package/src/duckdb/src/common/types/column/column_data_allocator.cpp +9 -6
- package/src/duckdb/src/common/types/column/column_data_collection.cpp +68 -2
- package/src/duckdb/src/common/types/column/column_data_collection_segment.cpp +20 -6
- package/src/duckdb/src/common/types/column/partitioned_column_data.cpp +2 -2
- package/src/duckdb/src/common/types/data_chunk.cpp +2 -2
- package/src/duckdb/src/common/types/date.cpp +15 -0
- package/src/duckdb/src/common/types/hugeint.cpp +40 -0
- package/src/duckdb/src/common/types/interval.cpp +3 -0
- package/src/duckdb/src/common/types/list_segment.cpp +56 -198
- package/src/duckdb/src/common/types/row/partitioned_tuple_data.cpp +3 -9
- package/src/duckdb/src/common/types/row/row_data_collection_scanner.cpp +35 -5
- package/src/duckdb/src/common/types/row/tuple_data_collection.cpp +2 -0
- package/src/duckdb/src/common/types/row/tuple_data_scatter_gather.cpp +2 -2
- package/src/duckdb/src/common/types/string_heap.cpp +4 -0
- package/src/duckdb/src/common/types/time.cpp +105 -0
- package/src/duckdb/src/common/types/timestamp.cpp +7 -0
- package/src/duckdb/src/common/types/uuid.cpp +2 -2
- package/src/duckdb/src/common/types/validity_mask.cpp +33 -0
- package/src/duckdb/src/common/types/value.cpp +65 -47
- package/src/duckdb/src/common/types/vector.cpp +52 -25
- package/src/duckdb/src/common/types.cpp +38 -724
- package/src/duckdb/src/common/virtual_file_system.cpp +142 -1
- package/src/duckdb/src/core_functions/aggregate/holistic/approximate_quantile.cpp +26 -0
- package/src/duckdb/src/core_functions/aggregate/holistic/mode.cpp +5 -7
- package/src/duckdb/src/core_functions/aggregate/holistic/quantile.cpp +64 -19
- package/src/duckdb/src/core_functions/aggregate/holistic/reservoir_quantile.cpp +30 -0
- package/src/duckdb/src/core_functions/aggregate/nested/histogram.cpp +1 -0
- package/src/duckdb/src/core_functions/aggregate/nested/list.cpp +83 -59
- package/src/duckdb/src/core_functions/aggregate/regression/regr_avg.cpp +4 -4
- package/src/duckdb/src/core_functions/aggregate/regression/regr_intercept.cpp +4 -4
- package/src/duckdb/src/core_functions/aggregate/regression/regr_r2.cpp +5 -4
- package/src/duckdb/src/core_functions/aggregate/regression/regr_sxx_syy.cpp +8 -8
- package/src/duckdb/src/core_functions/aggregate/regression/regr_sxy.cpp +4 -3
- package/src/duckdb/src/core_functions/function_list.cpp +10 -4
- package/src/duckdb/src/core_functions/scalar/date/date_diff.cpp +2 -0
- package/src/duckdb/src/core_functions/scalar/date/date_part.cpp +380 -89
- package/src/duckdb/src/core_functions/scalar/date/date_sub.cpp +2 -0
- package/src/duckdb/src/core_functions/scalar/date/date_trunc.cpp +4 -0
- package/src/duckdb/src/core_functions/scalar/date/epoch.cpp +10 -24
- package/src/duckdb/src/core_functions/scalar/date/make_date.cpp +19 -4
- package/src/duckdb/src/core_functions/scalar/date/strftime.cpp +10 -0
- package/src/duckdb/src/core_functions/scalar/debug/vector_type.cpp +23 -0
- package/src/duckdb/src/core_functions/scalar/list/array_slice.cpp +314 -82
- package/src/duckdb/src/core_functions/scalar/list/list_aggregates.cpp +4 -2
- package/src/duckdb/src/core_functions/scalar/list/list_lambdas.cpp +22 -3
- package/src/duckdb/src/core_functions/scalar/map/map_entries.cpp +2 -2
- package/src/duckdb/src/core_functions/scalar/string/to_base.cpp +66 -0
- package/src/duckdb/src/core_functions/scalar/union/union_tag.cpp +1 -1
- package/src/duckdb/src/execution/aggregate_hashtable.cpp +40 -18
- package/src/duckdb/src/execution/column_binding_resolver.cpp +10 -7
- package/src/duckdb/src/execution/expression_executor/execute_parameter.cpp +2 -2
- package/src/duckdb/src/execution/expression_executor.cpp +1 -1
- package/src/duckdb/src/execution/index/art/art.cpp +219 -259
- package/src/duckdb/src/execution/index/art/art_key.cpp +0 -11
- package/src/duckdb/src/execution/index/art/fixed_size_allocator.cpp +11 -15
- package/src/duckdb/src/execution/index/art/iterator.cpp +130 -214
- package/src/duckdb/src/execution/index/art/leaf.cpp +300 -266
- package/src/duckdb/src/execution/index/art/node.cpp +211 -205
- package/src/duckdb/src/execution/index/art/node16.cpp +10 -19
- package/src/duckdb/src/execution/index/art/node256.cpp +10 -18
- package/src/duckdb/src/execution/index/art/node4.cpp +21 -23
- package/src/duckdb/src/execution/index/art/node48.cpp +10 -20
- package/src/duckdb/src/execution/index/art/prefix.cpp +308 -338
- package/src/duckdb/src/execution/join_hashtable.cpp +4 -4
- package/src/duckdb/src/execution/operator/aggregate/aggregate_object.cpp +1 -0
- package/src/duckdb/src/execution/operator/aggregate/physical_hash_aggregate.cpp +14 -11
- package/src/duckdb/src/execution/operator/aggregate/physical_perfecthash_aggregate.cpp +6 -4
- package/src/duckdb/src/execution/operator/aggregate/physical_streaming_window.cpp +8 -3
- package/src/duckdb/src/execution/operator/aggregate/physical_ungrouped_aggregate.cpp +46 -34
- package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +332 -1067
- package/src/duckdb/src/execution/operator/filter/physical_filter.cpp +1 -1
- package/src/duckdb/src/execution/operator/helper/physical_batch_collector.cpp +12 -9
- package/src/duckdb/src/execution/operator/helper/physical_explain_analyze.cpp +2 -2
- package/src/duckdb/src/execution/operator/helper/physical_limit.cpp +10 -8
- package/src/duckdb/src/execution/operator/helper/physical_materialized_collector.cpp +7 -5
- package/src/duckdb/src/execution/operator/helper/physical_vacuum.cpp +7 -5
- package/src/duckdb/src/execution/operator/join/physical_asof_join.cpp +449 -288
- package/src/duckdb/src/execution/operator/join/physical_blockwise_nl_join.cpp +2 -2
- package/src/duckdb/src/execution/operator/join/physical_comparison_join.cpp +1 -2
- package/src/duckdb/src/execution/operator/join/physical_delim_join.cpp +13 -6
- package/src/duckdb/src/execution/operator/join/physical_hash_join.cpp +28 -15
- package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +35 -17
- package/src/duckdb/src/execution/operator/join/physical_join.cpp +1 -1
- package/src/duckdb/src/execution/operator/join/physical_nested_loop_join.cpp +7 -4
- package/src/duckdb/src/execution/operator/join/physical_piecewise_merge_join.cpp +31 -10
- package/src/duckdb/src/execution/operator/join/physical_range_join.cpp +41 -5
- package/src/duckdb/src/execution/operator/order/physical_order.cpp +7 -5
- package/src/duckdb/src/execution/operator/order/physical_top_n.cpp +7 -5
- package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +100 -13
- package/src/duckdb/src/execution/operator/persistent/csv_file_handle.cpp +1 -1
- package/src/duckdb/src/execution/operator/persistent/csv_reader_options.cpp +20 -0
- package/src/duckdb/src/execution/operator/persistent/csv_rejects_table.cpp +48 -0
- package/src/duckdb/src/execution/operator/persistent/parallel_csv_reader.cpp +2 -3
- package/src/duckdb/src/execution/operator/persistent/physical_batch_copy_to_file.cpp +14 -10
- package/src/duckdb/src/execution/operator/persistent/physical_batch_insert.cpp +11 -9
- package/src/duckdb/src/execution/operator/persistent/physical_copy_to_file.cpp +9 -7
- package/src/duckdb/src/execution/operator/persistent/physical_fixed_batch_copy.cpp +14 -12
- package/src/duckdb/src/execution/operator/persistent/physical_insert.cpp +11 -11
- package/src/duckdb/src/execution/operator/persistent/physical_update.cpp +4 -2
- package/src/duckdb/src/execution/operator/projection/physical_pivot.cpp +2 -1
- package/src/duckdb/src/execution/operator/projection/physical_unnest.cpp +24 -27
- package/src/duckdb/src/execution/operator/scan/physical_column_data_scan.cpp +19 -0
- package/src/duckdb/src/execution/operator/scan/physical_table_scan.cpp +7 -12
- package/src/duckdb/src/execution/operator/schema/physical_attach.cpp +2 -1
- package/src/duckdb/src/execution/operator/schema/physical_create_art_index.cpp +198 -0
- package/src/duckdb/src/execution/operator/schema/physical_create_type.cpp +2 -6
- package/src/duckdb/src/execution/operator/set/physical_cte.cpp +160 -0
- package/src/duckdb/src/execution/operator/set/physical_recursive_cte.cpp +15 -5
- package/src/duckdb/src/execution/partitionable_hashtable.cpp +41 -6
- package/src/duckdb/src/execution/perfect_aggregate_hashtable.cpp +37 -6
- package/src/duckdb/src/execution/physical_operator.cpp +20 -16
- package/src/duckdb/src/execution/physical_plan/plan_aggregate.cpp +43 -10
- package/src/duckdb/src/execution/physical_plan/plan_asof_join.cpp +57 -35
- package/src/duckdb/src/execution/physical_plan/plan_comparison_join.cpp +32 -15
- package/src/duckdb/src/execution/physical_plan/plan_create_index.cpp +45 -34
- package/src/duckdb/src/execution/physical_plan/plan_cte.cpp +33 -0
- package/src/duckdb/src/execution/physical_plan/plan_delim_join.cpp +2 -5
- package/src/duckdb/src/execution/physical_plan/plan_get.cpp +2 -2
- package/src/duckdb/src/execution/physical_plan/plan_recursive_cte.cpp +25 -4
- package/src/duckdb/src/execution/physical_plan_generator.cpp +6 -11
- package/src/duckdb/src/execution/radix_partitioned_hashtable.cpp +290 -43
- package/src/duckdb/src/execution/window_executor.cpp +1284 -0
- package/src/duckdb/src/execution/window_segment_tree.cpp +408 -144
- package/src/duckdb/src/function/aggregate/distributive/count.cpp +2 -13
- package/src/duckdb/src/function/aggregate/sorted_aggregate_function.cpp +6 -12
- package/src/duckdb/src/function/cast/bit_cast.cpp +34 -2
- package/src/duckdb/src/function/cast/blob_cast.cpp +3 -0
- package/src/duckdb/src/function/cast/numeric_casts.cpp +2 -0
- package/src/duckdb/src/function/cast/string_cast.cpp +2 -2
- package/src/duckdb/src/function/cast/time_casts.cpp +7 -6
- package/src/duckdb/src/function/function.cpp +3 -1
- package/src/duckdb/src/function/pragma/pragma_queries.cpp +5 -0
- package/src/duckdb/src/function/scalar/compressed_materialization/compress_integral.cpp +212 -0
- package/src/duckdb/src/function/scalar/compressed_materialization/compress_string.cpp +249 -0
- package/src/duckdb/src/function/scalar/compressed_materialization_functions.cpp +29 -0
- package/src/duckdb/src/function/scalar/list/list_resize.cpp +162 -0
- package/src/duckdb/src/function/scalar/nested_functions.cpp +1 -0
- package/src/duckdb/src/function/scalar/operators/add.cpp +9 -0
- package/src/duckdb/src/function/scalar/operators/arithmetic.cpp +6 -3
- package/src/duckdb/src/function/scalar/string/like.cpp +12 -4
- package/src/duckdb/src/function/scalar/system/aggregate_export.cpp +39 -5
- package/src/duckdb/src/function/scalar_function.cpp +5 -20
- package/src/duckdb/src/function/table/arrow/arrow_duck_schema.cpp +57 -0
- package/src/duckdb/src/function/table/arrow.cpp +110 -88
- package/src/duckdb/src/function/table/arrow_conversion.cpp +86 -73
- package/src/duckdb/src/function/table/copy_csv.cpp +8 -1
- package/src/duckdb/src/function/table/read_csv.cpp +124 -21
- package/src/duckdb/src/function/table/system/test_all_types.cpp +48 -21
- package/src/duckdb/src/function/table/system_functions.cpp +1 -0
- package/src/duckdb/src/function/table/table_scan.cpp +44 -0
- package/src/duckdb/src/function/table/version/pragma_version.cpp +49 -2
- package/src/duckdb/src/function/table_function.cpp +4 -3
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/index_catalog_entry.hpp +3 -3
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/macro_catalog_entry.hpp +1 -4
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/schema_catalog_entry.hpp +2 -5
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/sequence_catalog_entry.hpp +1 -6
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/table_catalog_entry.hpp +2 -13
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/type_catalog_entry.hpp +1 -4
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/view_catalog_entry.hpp +2 -5
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry.hpp +14 -0
- package/src/duckdb/src/include/duckdb/catalog/catalog_set.hpp +0 -6
- package/src/duckdb/src/include/duckdb/common/adbc/adbc.h +1 -0
- package/src/duckdb/src/include/duckdb/common/adbc/adbc.hpp +4 -1
- package/src/duckdb/src/include/duckdb/common/adbc/single_batch_array_stream.hpp +16 -0
- package/src/duckdb/src/include/duckdb/common/allocator.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/arrow/appender/append_data.hpp +109 -0
- package/src/duckdb/src/include/duckdb/common/arrow/appender/bool_data.hpp +15 -0
- package/src/duckdb/src/include/duckdb/common/arrow/appender/enum_data.hpp +69 -0
- package/src/duckdb/src/include/duckdb/common/arrow/appender/list.hpp +8 -0
- package/src/duckdb/src/include/duckdb/common/arrow/appender/list_data.hpp +18 -0
- package/src/duckdb/src/include/duckdb/common/arrow/appender/map_data.hpp +18 -0
- package/src/duckdb/src/include/duckdb/common/arrow/appender/scalar_data.hpp +88 -0
- package/src/duckdb/src/include/duckdb/common/arrow/appender/struct_data.hpp +18 -0
- package/src/duckdb/src/include/duckdb/common/arrow/appender/union_data.hpp +21 -0
- package/src/duckdb/src/include/duckdb/common/arrow/appender/varchar_data.hpp +105 -0
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_appender.hpp +9 -4
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_converter.hpp +3 -5
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_wrapper.hpp +5 -3
- package/src/duckdb/src/include/duckdb/common/arrow/nanoarrow/nanoarrow.h +462 -0
- package/src/duckdb/src/include/duckdb/common/arrow/nanoarrow/nanoarrow.hpp +14 -0
- package/src/duckdb/src/include/duckdb/common/arrow/result_arrow_wrapper.hpp +4 -0
- package/src/duckdb/src/include/duckdb/common/assert.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/bitpacking.hpp +70 -55
- package/src/duckdb/src/include/duckdb/common/bswap.hpp +42 -0
- package/src/duckdb/src/include/duckdb/common/case_insensitive_map.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/constants.hpp +4 -0
- package/src/duckdb/src/include/duckdb/common/dl.hpp +3 -1
- package/src/duckdb/src/include/duckdb/common/enum_util.hpp +660 -580
- package/src/duckdb/src/include/duckdb/common/enums/cte_materialize.hpp +21 -0
- package/src/duckdb/src/include/duckdb/common/enums/date_part_specifier.hpp +9 -1
- package/src/duckdb/src/include/duckdb/common/enums/index_type.hpp +4 -3
- package/src/duckdb/src/include/duckdb/common/enums/joinref_type.hpp +2 -1
- package/src/duckdb/src/include/duckdb/common/enums/logical_operator_type.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/enums/operator_result_type.hpp +5 -1
- package/src/duckdb/src/include/duckdb/common/enums/optimizer_type.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/enums/pending_execution_result.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/enums/physical_operator_type.hpp +2 -0
- package/src/duckdb/src/include/duckdb/common/extra_operator_info.hpp +27 -0
- package/src/duckdb/src/include/duckdb/common/extra_type_info.hpp +215 -0
- package/src/duckdb/src/include/duckdb/common/field_writer.hpp +0 -4
- package/src/duckdb/src/include/duckdb/common/file_system.hpp +10 -8
- package/src/duckdb/src/include/duckdb/common/filename_pattern.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/helper.hpp +8 -3
- package/src/duckdb/src/include/duckdb/common/hive_partitioning.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/http_state.hpp +61 -28
- package/src/duckdb/src/include/duckdb/common/hugeint.hpp +15 -0
- package/src/duckdb/src/include/duckdb/common/index_vector.hpp +12 -0
- package/src/duckdb/src/include/duckdb/common/limits.hpp +52 -149
- package/src/duckdb/src/include/duckdb/common/multi_file_reader.hpp +11 -5
- package/src/duckdb/src/include/duckdb/common/multi_file_reader_options.hpp +12 -42
- package/src/duckdb/src/include/duckdb/common/mutex.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/numeric_utils.hpp +48 -0
- package/src/duckdb/src/include/duckdb/common/opener_file_system.hpp +6 -2
- package/src/duckdb/src/include/duckdb/common/operator/add.hpp +5 -2
- package/src/duckdb/src/include/duckdb/common/operator/cast_operators.hpp +65 -4
- package/src/duckdb/src/include/duckdb/common/operator/multiply.hpp +3 -2
- package/src/duckdb/src/include/duckdb/common/operator/numeric_cast.hpp +10 -0
- package/src/duckdb/src/include/duckdb/common/operator/string_cast.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/operator/subtract.hpp +3 -2
- package/src/duckdb/src/include/duckdb/common/radix.hpp +9 -20
- package/src/duckdb/src/include/duckdb/common/radix_partitioning.hpp +6 -21
- package/src/duckdb/src/include/duckdb/common/row_operations/row_operations.hpp +3 -3
- package/src/duckdb/src/include/duckdb/common/serializer/binary_deserializer.hpp +35 -7
- package/src/duckdb/src/include/duckdb/common/serializer/binary_serializer.hpp +14 -6
- package/src/duckdb/src/include/duckdb/common/serializer/buffered_file_reader.hpp +0 -4
- package/src/duckdb/src/include/duckdb/common/serializer/deserialization_data.hpp +110 -0
- package/src/duckdb/src/include/duckdb/common/serializer/format_deserializer.hpp +94 -16
- package/src/duckdb/src/include/duckdb/common/serializer/format_serializer.hpp +73 -40
- package/src/duckdb/src/include/duckdb/common/serializer/serialization_traits.hpp +26 -4
- package/src/duckdb/src/include/duckdb/common/serializer.hpp +0 -7
- package/src/duckdb/src/include/duckdb/common/sort/partition_state.hpp +23 -8
- package/src/duckdb/src/include/duckdb/common/stack_checker.hpp +34 -0
- package/src/duckdb/src/include/duckdb/common/string_util.hpp +11 -0
- package/src/duckdb/src/include/duckdb/common/type_util.hpp +8 -0
- package/src/duckdb/src/include/duckdb/common/typedefs.hpp +8 -0
- package/src/duckdb/src/include/duckdb/common/types/batched_data_collection.hpp +3 -1
- package/src/duckdb/src/include/duckdb/common/types/bit.hpp +81 -0
- package/src/duckdb/src/include/duckdb/common/types/column/column_data_allocator.hpp +11 -1
- package/src/duckdb/src/include/duckdb/common/types/column/column_data_collection.hpp +12 -1
- package/src/duckdb/src/include/duckdb/common/types/column/column_data_collection_segment.hpp +3 -1
- package/src/duckdb/src/include/duckdb/common/types/column/column_data_scan_states.hpp +3 -1
- package/src/duckdb/src/include/duckdb/common/types/data_chunk.hpp +1 -3
- package/src/duckdb/src/include/duckdb/common/types/date.hpp +9 -5
- package/src/duckdb/src/include/duckdb/common/types/datetime.hpp +46 -3
- package/src/duckdb/src/include/duckdb/common/types/list_segment.hpp +11 -15
- package/src/duckdb/src/include/duckdb/common/types/row/partitioned_tuple_data.hpp +5 -2
- package/src/duckdb/src/include/duckdb/common/types/row/row_data_collection_scanner.hpp +5 -1
- package/src/duckdb/src/include/duckdb/common/types/row/tuple_data_collection.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/types/row/tuple_data_states.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/types/string_heap.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/types/string_type.hpp +9 -0
- package/src/duckdb/src/include/duckdb/common/types/time.hpp +5 -0
- package/src/duckdb/src/include/duckdb/common/types/timestamp.hpp +16 -10
- package/src/duckdb/src/include/duckdb/common/types/value.hpp +7 -2
- package/src/duckdb/src/include/duckdb/common/types/vector.hpp +7 -0
- package/src/duckdb/src/include/duckdb/common/types.hpp +6 -25
- package/src/duckdb/src/include/duckdb/common/vector_operations/aggregate_executor.hpp +7 -2
- package/src/duckdb/src/include/duckdb/common/virtual_file_system.hpp +40 -97
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/algebraic/corr.hpp +4 -4
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/algebraic/covar.hpp +3 -1
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/algebraic_functions.hpp +3 -1
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/distributive_functions.hpp +4 -2
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/holistic_functions.hpp +3 -1
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/nested_functions.hpp +3 -1
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/regression/regr_count.hpp +1 -0
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/regression/regr_slope.hpp +3 -3
- package/src/duckdb/src/include/duckdb/core_functions/aggregate/regression_functions.hpp +3 -1
- package/src/duckdb/src/include/duckdb/core_functions/scalar/bit_functions.hpp +3 -1
- package/src/duckdb/src/include/duckdb/core_functions/scalar/blob_functions.hpp +3 -1
- package/src/duckdb/src/include/duckdb/core_functions/scalar/date_functions.hpp +40 -11
- package/src/duckdb/src/include/duckdb/core_functions/scalar/debug_functions.hpp +27 -0
- package/src/duckdb/src/include/duckdb/core_functions/scalar/enum_functions.hpp +3 -1
- package/src/duckdb/src/include/duckdb/core_functions/scalar/generic_functions.hpp +3 -1
- package/src/duckdb/src/include/duckdb/core_functions/scalar/list_functions.hpp +7 -5
- package/src/duckdb/src/include/duckdb/core_functions/scalar/map_functions.hpp +3 -1
- package/src/duckdb/src/include/duckdb/core_functions/scalar/math_functions.hpp +6 -4
- package/src/duckdb/src/include/duckdb/core_functions/scalar/operators_functions.hpp +4 -2
- package/src/duckdb/src/include/duckdb/core_functions/scalar/random_functions.hpp +3 -1
- package/src/duckdb/src/include/duckdb/core_functions/scalar/string_functions.hpp +12 -1
- package/src/duckdb/src/include/duckdb/core_functions/scalar/struct_functions.hpp +3 -1
- package/src/duckdb/src/include/duckdb/core_functions/scalar/union_functions.hpp +3 -1
- package/src/duckdb/src/include/duckdb/execution/aggregate_hashtable.hpp +21 -3
- package/src/duckdb/src/include/duckdb/execution/executor.hpp +3 -0
- package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +13 -12
- package/src/duckdb/src/include/duckdb/execution/index/art/art_key.hpp +0 -1
- package/src/duckdb/src/include/duckdb/execution/index/art/fixed_size_allocator.hpp +22 -24
- package/src/duckdb/src/include/duckdb/execution/index/art/iterator.hpp +32 -28
- package/src/duckdb/src/include/duckdb/execution/index/art/leaf.hpp +46 -51
- package/src/duckdb/src/include/duckdb/execution/index/art/node.hpp +134 -53
- package/src/duckdb/src/include/duckdb/execution/index/art/node16.hpp +5 -7
- package/src/duckdb/src/include/duckdb/execution/index/art/node256.hpp +5 -7
- package/src/duckdb/src/include/duckdb/execution/index/art/node4.hpp +7 -9
- package/src/duckdb/src/include/duckdb/execution/index/art/node48.hpp +5 -7
- package/src/duckdb/src/include/duckdb/execution/index/art/prefix.hpp +63 -52
- package/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_hash_aggregate.hpp +3 -3
- package/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_perfecthash_aggregate.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_ungrouped_aggregate.hpp +3 -3
- package/src/duckdb/src/include/duckdb/execution/operator/aggregate/physical_window.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/helper/physical_batch_collector.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/helper/physical_explain_analyze.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/helper/physical_limit.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/helper/physical_materialized_collector.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/helper/physical_vacuum.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_asof_join.hpp +5 -12
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_blockwise_nl_join.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_delim_join.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_hash_join.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_iejoin.hpp +3 -3
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_nested_loop_join.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_piecewise_merge_join.hpp +3 -3
- package/src/duckdb/src/include/duckdb/execution/operator/join/physical_range_join.hpp +12 -1
- package/src/duckdb/src/include/duckdb/execution/operator/order/physical_order.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/order/physical_top_n.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/base_csv_reader.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_line_info.hpp +4 -3
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +10 -1
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_rejects_table.hpp +36 -0
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/parallel_csv_reader.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_batch_copy_to_file.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_batch_insert.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_copy_to_file.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_fixed_batch_copy.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_insert.hpp +2 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/physical_update.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/operator/scan/physical_column_data_scan.hpp +10 -0
- package/src/duckdb/src/include/duckdb/execution/operator/scan/physical_table_scan.hpp +5 -5
- package/src/duckdb/src/include/duckdb/execution/operator/schema/{physical_create_index.hpp → physical_create_art_index.hpp} +14 -7
- package/src/duckdb/src/include/duckdb/execution/operator/set/physical_cte.hpp +62 -0
- package/src/duckdb/src/include/duckdb/execution/operator/set/physical_recursive_cte.hpp +8 -2
- package/src/duckdb/src/include/duckdb/execution/partitionable_hashtable.hpp +5 -1
- package/src/duckdb/src/include/duckdb/execution/perfect_aggregate_hashtable.hpp +4 -2
- package/src/duckdb/src/include/duckdb/execution/physical_operator.hpp +6 -5
- package/src/duckdb/src/include/duckdb/execution/physical_operator_states.hpp +11 -0
- package/src/duckdb/src/include/duckdb/execution/physical_plan_generator.hpp +6 -2
- package/src/duckdb/src/include/duckdb/execution/radix_partitioned_hashtable.hpp +10 -3
- package/src/duckdb/src/include/duckdb/execution/window_executor.hpp +313 -0
- package/src/duckdb/src/include/duckdb/execution/window_segment_tree.hpp +79 -63
- package/src/duckdb/src/include/duckdb/function/aggregate_function.hpp +12 -4
- package/src/duckdb/src/include/duckdb/function/aggregate_state.hpp +2 -2
- package/src/duckdb/src/include/duckdb/function/built_in_functions.hpp +1 -0
- package/src/duckdb/src/include/duckdb/function/copy_function.hpp +6 -1
- package/src/duckdb/src/include/duckdb/function/function_serialization.hpp +81 -0
- package/src/duckdb/src/include/duckdb/function/macro_function.hpp +3 -0
- package/src/duckdb/src/include/duckdb/function/scalar/compressed_materialization_functions.hpp +49 -0
- package/src/duckdb/src/include/duckdb/function/scalar/list/contains_or_position.hpp +1 -1
- package/src/duckdb/src/include/duckdb/function/scalar/nested_functions.hpp +5 -0
- package/src/duckdb/src/include/duckdb/function/scalar/strftime_format.hpp +8 -0
- package/src/duckdb/src/include/duckdb/function/scalar/string_functions.hpp +2 -0
- package/src/duckdb/src/include/duckdb/function/scalar_function.hpp +8 -3
- package/src/duckdb/src/include/duckdb/function/scalar_macro_function.hpp +3 -0
- package/src/duckdb/src/include/duckdb/function/table/arrow/arrow_duck_schema.hpp +99 -0
- package/src/duckdb/src/include/duckdb/function/table/arrow.hpp +6 -36
- package/src/duckdb/src/include/duckdb/function/table/read_csv.hpp +7 -0
- package/src/duckdb/src/include/duckdb/function/table/system_functions.hpp +5 -1
- package/src/duckdb/src/include/duckdb/function/table_function.hpp +8 -0
- package/src/duckdb/src/include/duckdb/function/table_macro_function.hpp +3 -0
- package/src/duckdb/src/include/duckdb/function/udf_function.hpp +2 -1
- package/src/duckdb/src/include/duckdb/main/attached_database.hpp +1 -1
- package/src/duckdb/src/include/duckdb/main/capi/capi_internal.hpp +4 -3
- package/src/duckdb/src/include/duckdb/main/chunk_scan_state/query_result.hpp +29 -0
- package/src/duckdb/src/include/duckdb/main/chunk_scan_state.hpp +43 -0
- package/src/duckdb/src/include/duckdb/main/client_config.hpp +5 -2
- package/src/duckdb/src/include/duckdb/main/client_context.hpp +16 -14
- package/src/duckdb/src/include/duckdb/main/client_properties.hpp +25 -0
- package/src/duckdb/src/include/duckdb/main/config.hpp +3 -1
- package/src/duckdb/src/include/duckdb/main/connection.hpp +1 -2
- package/src/duckdb/src/include/duckdb/main/extension/generated_extension_loader.hpp +22 -0
- package/src/duckdb/src/include/duckdb/main/extension_entries.hpp +8 -0
- package/src/duckdb/src/include/duckdb/main/extension_util.hpp +4 -0
- package/src/duckdb/src/include/duckdb/main/pending_query_result.hpp +5 -0
- package/src/duckdb/src/include/duckdb/main/prepared_statement.hpp +73 -5
- package/src/duckdb/src/include/duckdb/main/prepared_statement_data.hpp +6 -6
- package/src/duckdb/src/include/duckdb/main/query_result.hpp +2 -27
- package/src/duckdb/src/include/duckdb/main/relation/aggregate_relation.hpp +4 -1
- package/src/duckdb/src/include/duckdb/main/relation/cross_product_relation.hpp +4 -1
- package/src/duckdb/src/include/duckdb/main/relation/join_relation.hpp +5 -2
- package/src/duckdb/src/include/duckdb/main/relation.hpp +4 -2
- package/src/duckdb/src/include/duckdb/main/settings.hpp +41 -11
- package/src/duckdb/src/include/duckdb/optimizer/column_binding_replacer.hpp +47 -0
- package/src/duckdb/src/include/duckdb/optimizer/compressed_materialization.hpp +132 -0
- package/src/duckdb/src/include/duckdb/optimizer/deliminator.hpp +13 -16
- package/src/duckdb/src/include/duckdb/optimizer/filter_pushdown.hpp +7 -0
- package/src/duckdb/src/include/duckdb/optimizer/join_order/cardinality_estimator.hpp +38 -64
- package/src/duckdb/src/include/duckdb/optimizer/join_order/cost_model.hpp +37 -0
- package/src/duckdb/src/include/duckdb/optimizer/join_order/estimated_properties.hpp +10 -1
- package/src/duckdb/src/include/duckdb/optimizer/join_order/join_node.hpp +14 -29
- package/src/duckdb/src/include/duckdb/optimizer/join_order/join_order_optimizer.hpp +8 -22
- package/src/duckdb/src/include/duckdb/optimizer/join_order/join_relation.hpp +1 -12
- package/src/duckdb/src/include/duckdb/optimizer/join_order/plan_enumerator.hpp +89 -0
- package/src/duckdb/src/include/duckdb/optimizer/join_order/query_graph.hpp +19 -30
- package/src/duckdb/src/include/duckdb/optimizer/join_order/query_graph_manager.hpp +113 -0
- package/src/duckdb/src/include/duckdb/optimizer/join_order/relation_manager.hpp +73 -0
- package/src/duckdb/src/include/duckdb/optimizer/join_order/relation_statistics_helper.hpp +73 -0
- package/src/duckdb/src/include/duckdb/optimizer/matcher/set_matcher.hpp +13 -0
- package/src/duckdb/src/include/duckdb/optimizer/optimizer.hpp +3 -0
- package/src/duckdb/src/include/duckdb/optimizer/remove_duplicate_groups.hpp +40 -0
- package/src/duckdb/src/include/duckdb/optimizer/statistics_propagator.hpp +11 -3
- package/src/duckdb/src/include/duckdb/optimizer/topn_optimizer.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parallel/pipeline.hpp +2 -3
- package/src/duckdb/src/include/duckdb/parallel/pipeline_executor.hpp +3 -2
- package/src/duckdb/src/include/duckdb/parallel/task_scheduler.hpp +9 -1
- package/src/duckdb/src/include/duckdb/parser/column_definition.hpp +6 -5
- package/src/duckdb/src/include/duckdb/parser/column_list.hpp +4 -0
- package/src/duckdb/src/include/duckdb/parser/common_table_expression_info.hpp +2 -0
- package/src/duckdb/src/include/duckdb/parser/constraint.hpp +5 -0
- package/src/duckdb/src/include/duckdb/parser/constraints/check_constraint.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/constraints/foreign_key_constraint.hpp +6 -0
- package/src/duckdb/src/include/duckdb/parser/constraints/not_null_constraint.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/constraints/unique_constraint.hpp +6 -0
- package/src/duckdb/src/include/duckdb/parser/expression/between_expression.hpp +4 -1
- package/src/duckdb/src/include/duckdb/parser/expression/case_expression.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/expression/cast_expression.hpp +4 -1
- package/src/duckdb/src/include/duckdb/parser/expression/collate_expression.hpp +4 -1
- package/src/duckdb/src/include/duckdb/parser/expression/columnref_expression.hpp +4 -1
- package/src/duckdb/src/include/duckdb/parser/expression/comparison_expression.hpp +4 -1
- package/src/duckdb/src/include/duckdb/parser/expression/conjunction_expression.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/expression/constant_expression.hpp +4 -1
- package/src/duckdb/src/include/duckdb/parser/expression/default_expression.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/expression/function_expression.hpp +4 -1
- package/src/duckdb/src/include/duckdb/parser/expression/lambda_expression.hpp +4 -1
- package/src/duckdb/src/include/duckdb/parser/expression/operator_expression.hpp +21 -4
- package/src/duckdb/src/include/duckdb/parser/expression/parameter_expression.hpp +18 -2
- package/src/duckdb/src/include/duckdb/parser/expression/positional_reference_expression.hpp +4 -1
- package/src/duckdb/src/include/duckdb/parser/expression/star_expression.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/expression/subquery_expression.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/expression/window_expression.hpp +4 -1
- package/src/duckdb/src/include/duckdb/parser/group_by_node.hpp +11 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_info.hpp +12 -1
- package/src/duckdb/src/include/duckdb/parser/parsed_data/alter_table_info.hpp +66 -2
- package/src/duckdb/src/include/duckdb/parser/parsed_data/attach_info.hpp +8 -1
- package/src/duckdb/src/include/duckdb/parser/parsed_data/copy_info.hpp +8 -1
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_index_info.hpp +9 -1
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_info.hpp +9 -2
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_macro_info.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_schema_info.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_sequence_info.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_table_info.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_type_info.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_view_info.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/detach_info.hpp +7 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/drop_info.hpp +7 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/exported_table_data.hpp +7 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/load_info.hpp +13 -3
- package/src/duckdb/src/include/duckdb/parser/parsed_data/parse_info.hpp +22 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/pragma_info.hpp +10 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/show_select_info.hpp +7 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/transaction_info.hpp +10 -0
- package/src/duckdb/src/include/duckdb/parser/parsed_data/vacuum_info.hpp +10 -0
- package/src/duckdb/src/include/duckdb/parser/parser.hpp +4 -0
- package/src/duckdb/src/include/duckdb/parser/query_node/cte_node.hpp +54 -0
- package/src/duckdb/src/include/duckdb/parser/query_node/list.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/query_node.hpp +2 -1
- package/src/duckdb/src/include/duckdb/parser/statement/execute_statement.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/tableref/emptytableref.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/tableref/joinref.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/tableref/subqueryref.hpp +3 -0
- package/src/duckdb/src/include/duckdb/parser/tokens.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/transformer.hpp +23 -26
- package/src/duckdb/src/include/duckdb/planner/binder.hpp +12 -5
- package/src/duckdb/src/include/duckdb/planner/bound_constraint.hpp +0 -8
- package/src/duckdb/src/include/duckdb/planner/bound_parameter_map.hpp +2 -1
- package/src/duckdb/src/include/duckdb/planner/bound_result_modifier.hpp +6 -0
- package/src/duckdb/src/include/duckdb/planner/bound_tokens.hpp +1 -0
- package/src/duckdb/src/include/duckdb/planner/column_binding.hpp +9 -0
- package/src/duckdb/src/include/duckdb/planner/constraints/bound_unique_constraint.hpp +3 -3
- package/src/duckdb/src/include/duckdb/planner/expression/bound_aggregate_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_between_expression.hpp +6 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_case_expression.hpp +6 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_cast_expression.hpp +6 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_columnref_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_comparison_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_conjunction_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_constant_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_default_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_function_expression.hpp +4 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_lambda_expression.hpp +3 -1
- package/src/duckdb/src/include/duckdb/planner/expression/bound_lambdaref_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_operator_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_parameter_data.hpp +24 -6
- package/src/duckdb/src/include/duckdb/planner/expression/bound_parameter_expression.hpp +9 -2
- package/src/duckdb/src/include/duckdb/planner/expression/bound_reference_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_unnest_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_window_expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression/list.hpp +1 -0
- package/src/duckdb/src/include/duckdb/planner/expression.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/expression_binder/lateral_binder.hpp +0 -2
- package/src/duckdb/src/include/duckdb/planner/expression_binder.hpp +13 -1
- package/src/duckdb/src/include/duckdb/planner/filter/conjunction_filter.hpp +4 -0
- package/src/duckdb/src/include/duckdb/planner/filter/constant_filter.hpp +2 -0
- package/src/duckdb/src/include/duckdb/planner/filter/null_filter.hpp +4 -0
- package/src/duckdb/src/include/duckdb/planner/joinside.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/logical_operator.hpp +3 -2
- package/src/duckdb/src/include/duckdb/planner/logical_tokens.hpp +1 -2
- package/src/duckdb/src/include/duckdb/planner/operator/list.hpp +3 -3
- package/src/duckdb/src/include/duckdb/planner/operator/logical_aggregate.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_any_join.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_column_data_get.hpp +4 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_comparison_join.hpp +12 -7
- package/src/duckdb/src/include/duckdb/planner/operator/logical_copy_to_file.hpp +2 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_create.hpp +9 -6
- package/src/duckdb/src/include/duckdb/planner/operator/logical_create_index.hpp +12 -23
- package/src/duckdb/src/include/duckdb/planner/operator/logical_create_table.hpp +10 -6
- package/src/duckdb/src/include/duckdb/planner/operator/logical_cross_product.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_cteref.hpp +9 -2
- package/src/duckdb/src/include/duckdb/planner/operator/logical_delete.hpp +7 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_delim_get.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_dependent_join.hpp +43 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_distinct.hpp +6 -10
- package/src/duckdb/src/include/duckdb/planner/operator/logical_dummy_scan.hpp +2 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_empty_result.hpp +2 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_explain.hpp +4 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_expression_get.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_extension_operator.hpp +8 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_filter.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_get.hpp +11 -1
- package/src/duckdb/src/include/duckdb/planner/operator/logical_insert.hpp +6 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_limit.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_limit_percent.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_materialized_cte.hpp +52 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_order.hpp +7 -35
- package/src/duckdb/src/include/duckdb/planner/operator/logical_pivot.hpp +6 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_positional_join.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_projection.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_recursive_cte.hpp +10 -7
- package/src/duckdb/src/include/duckdb/planner/operator/logical_reset.hpp +4 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_sample.hpp +6 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_set.hpp +4 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_set_operation.hpp +4 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_show.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_simple.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_top_n.hpp +4 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_unnest.hpp +2 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_update.hpp +6 -0
- package/src/duckdb/src/include/duckdb/planner/operator/logical_window.hpp +3 -0
- package/src/duckdb/src/include/duckdb/planner/operator_extension.hpp +1 -0
- package/src/duckdb/src/include/duckdb/planner/planner.hpp +4 -3
- package/src/duckdb/src/include/duckdb/planner/query_node/bound_cte_node.hpp +44 -0
- package/src/duckdb/src/include/duckdb/planner/query_node/list.hpp +1 -0
- package/src/duckdb/src/include/duckdb/planner/subquery/flatten_dependent_join.hpp +2 -2
- package/src/duckdb/src/include/duckdb/planner/subquery/has_correlated_expressions.hpp +4 -1
- package/src/duckdb/src/include/duckdb/planner/subquery/recursive_dependent_join_planner.hpp +31 -0
- package/src/duckdb/src/include/duckdb/planner/subquery/rewrite_correlated_expressions.hpp +8 -2
- package/src/duckdb/src/include/duckdb/planner/table_filter.hpp +7 -1
- package/src/duckdb/src/include/duckdb/planner/tableref/bound_cteref.hpp +5 -2
- package/src/duckdb/src/include/duckdb/planner/tableref/bound_pivotref.hpp +3 -0
- package/src/duckdb/src/include/duckdb/storage/arena_allocator.hpp +2 -1
- package/src/duckdb/src/include/duckdb/storage/block.hpp +27 -4
- package/src/duckdb/src/include/duckdb/storage/block_manager.hpp +11 -11
- package/src/duckdb/src/include/duckdb/storage/checkpoint/row_group_writer.hpp +5 -5
- package/src/duckdb/src/include/duckdb/storage/checkpoint/table_data_reader.hpp +2 -2
- package/src/duckdb/src/include/duckdb/storage/checkpoint/table_data_writer.hpp +3 -3
- package/src/duckdb/src/include/duckdb/storage/checkpoint_manager.hpp +19 -16
- package/src/duckdb/src/include/duckdb/storage/data_pointer.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/data_table.hpp +2 -2
- package/src/duckdb/src/include/duckdb/storage/in_memory_block_manager.hpp +2 -2
- package/src/duckdb/src/include/duckdb/storage/index.hpp +2 -2
- package/src/duckdb/src/include/duckdb/storage/metadata/metadata_manager.hpp +88 -0
- package/src/duckdb/src/include/duckdb/storage/metadata/metadata_reader.hpp +54 -0
- package/src/duckdb/src/include/duckdb/storage/metadata/metadata_writer.hpp +45 -0
- package/src/duckdb/src/include/duckdb/storage/object_cache.hpp +22 -0
- package/src/duckdb/src/include/duckdb/storage/partial_block_manager.hpp +2 -2
- package/src/duckdb/src/include/duckdb/storage/single_file_block_manager.hpp +8 -5
- package/src/duckdb/src/include/duckdb/storage/statistics/string_stats.hpp +4 -0
- package/src/duckdb/src/include/duckdb/storage/storage_info.hpp +2 -2
- package/src/duckdb/src/include/duckdb/storage/storage_manager.hpp +2 -2
- package/src/duckdb/src/include/duckdb/storage/table/chunk_info.hpp +3 -0
- package/src/duckdb/src/include/duckdb/storage/table/persistent_table_data.hpp +2 -2
- package/src/duckdb/src/include/duckdb/storage/table/row_group.hpp +4 -3
- package/src/duckdb/src/include/duckdb/storage/table/row_group_collection.hpp +3 -3
- package/src/duckdb/src/include/duckdb/storage/table/row_group_segment_tree.hpp +2 -2
- package/src/duckdb/src/include/duckdb/storage/table/table_index_list.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/table_io_manager.hpp +3 -0
- package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +3 -4
- package/src/duckdb/src/include/duckdb/transaction/local_storage.hpp +2 -3
- package/src/duckdb/src/include/duckdb/verification/prepared_statement_verifier.hpp +1 -1
- package/src/duckdb/src/include/duckdb.h +86 -1
- package/src/duckdb/src/main/appender.cpp +3 -1
- package/src/duckdb/src/main/attached_database.cpp +2 -2
- package/src/duckdb/src/main/capi/arrow-c.cpp +196 -8
- package/src/duckdb/src/main/capi/duckdb-c.cpp +16 -0
- package/src/duckdb/src/main/capi/duckdb_value-c.cpp +1 -1
- package/src/duckdb/src/main/capi/pending-c.cpp +23 -0
- package/src/duckdb/src/main/capi/prepared-c.cpp +106 -28
- package/src/duckdb/src/main/capi/result-c.cpp +3 -1
- package/src/duckdb/src/main/chunk_scan_state/query_result.cpp +53 -0
- package/src/duckdb/src/main/chunk_scan_state.cpp +48 -0
- package/src/duckdb/src/main/client_context.cpp +42 -19
- package/src/duckdb/src/main/client_verify.cpp +17 -0
- package/src/duckdb/src/main/config.cpp +4 -1
- package/src/duckdb/src/main/database.cpp +2 -11
- package/src/duckdb/src/main/db_instance_cache.cpp +14 -6
- package/src/duckdb/src/main/extension/extension_helper.cpp +107 -88
- package/src/duckdb/src/main/extension/extension_install.cpp +10 -1
- package/src/duckdb/src/main/extension/extension_load.cpp +26 -6
- package/src/duckdb/src/main/extension/extension_util.cpp +16 -0
- package/src/duckdb/src/main/pending_query_result.cpp +9 -1
- package/src/duckdb/src/main/prepared_statement.cpp +38 -11
- package/src/duckdb/src/main/prepared_statement_data.cpp +23 -18
- package/src/duckdb/src/main/query_result.cpp +0 -21
- package/src/duckdb/src/main/relation/aggregate_relation.cpp +20 -10
- package/src/duckdb/src/main/relation/cross_product_relation.cpp +4 -3
- package/src/duckdb/src/main/relation/join_relation.cpp +6 -6
- package/src/duckdb/src/main/relation.cpp +10 -9
- package/src/duckdb/src/main/settings/settings.cpp +79 -33
- package/src/duckdb/src/optimizer/column_binding_replacer.cpp +43 -0
- package/src/duckdb/src/optimizer/column_lifetime_analyzer.cpp +2 -4
- package/src/duckdb/src/optimizer/compressed_materialization/compress_aggregate.cpp +140 -0
- package/src/duckdb/src/optimizer/compressed_materialization/compress_distinct.cpp +42 -0
- package/src/duckdb/src/optimizer/compressed_materialization/compress_order.cpp +65 -0
- package/src/duckdb/src/optimizer/compressed_materialization.cpp +477 -0
- package/src/duckdb/src/optimizer/deliminator.cpp +180 -323
- package/src/duckdb/src/optimizer/filter_pushdown.cpp +23 -6
- package/src/duckdb/src/optimizer/join_order/cardinality_estimator.cpp +79 -325
- package/src/duckdb/src/optimizer/join_order/cost_model.cpp +19 -0
- package/src/duckdb/src/optimizer/join_order/estimated_properties.cpp +7 -0
- package/src/duckdb/src/optimizer/join_order/join_node.cpp +5 -37
- package/src/duckdb/src/optimizer/join_order/join_order_optimizer.cpp +48 -1047
- package/src/duckdb/src/optimizer/join_order/join_relation_set.cpp +2 -6
- package/src/duckdb/src/optimizer/join_order/plan_enumerator.cpp +552 -0
- package/src/duckdb/src/optimizer/join_order/query_graph.cpp +52 -41
- package/src/duckdb/src/optimizer/join_order/query_graph_manager.cpp +409 -0
- package/src/duckdb/src/optimizer/join_order/relation_manager.cpp +356 -0
- package/src/duckdb/src/optimizer/join_order/relation_statistics_helper.cpp +351 -0
- package/src/duckdb/src/optimizer/optimizer.cpp +49 -14
- package/src/duckdb/src/optimizer/pushdown/pushdown_cross_product.cpp +5 -5
- package/src/duckdb/src/optimizer/pushdown/pushdown_get.cpp +0 -1
- package/src/duckdb/src/optimizer/pushdown/pushdown_projection.cpp +34 -7
- package/src/duckdb/src/optimizer/remove_duplicate_groups.cpp +127 -0
- package/src/duckdb/src/optimizer/remove_unused_columns.cpp +4 -0
- package/src/duckdb/src/optimizer/rule/regex_optimizations.cpp +154 -15
- package/src/duckdb/src/optimizer/statistics/operator/propagate_join.cpp +65 -8
- package/src/duckdb/src/optimizer/statistics/operator/propagate_order.cpp +1 -1
- package/src/duckdb/src/optimizer/statistics_propagator.cpp +7 -5
- package/src/duckdb/src/optimizer/topn_optimizer.cpp +27 -10
- package/src/duckdb/src/optimizer/unnest_rewriter.cpp +3 -5
- package/src/duckdb/src/parallel/executor.cpp +25 -1
- package/src/duckdb/src/parallel/pipeline.cpp +0 -17
- package/src/duckdb/src/parallel/pipeline_executor.cpp +33 -13
- package/src/duckdb/src/parallel/pipeline_finish_event.cpp +55 -1
- package/src/duckdb/src/parallel/task_scheduler.cpp +18 -2
- package/src/duckdb/src/parser/column_definition.cpp +20 -32
- package/src/duckdb/src/parser/column_list.cpp +8 -0
- package/src/duckdb/src/parser/constraints/foreign_key_constraint.cpp +3 -0
- package/src/duckdb/src/parser/constraints/unique_constraint.cpp +3 -0
- package/src/duckdb/src/parser/expression/between_expression.cpp +3 -15
- package/src/duckdb/src/parser/expression/case_expression.cpp +0 -25
- package/src/duckdb/src/parser/expression/cast_expression.cpp +3 -14
- package/src/duckdb/src/parser/expression/collate_expression.cpp +3 -13
- package/src/duckdb/src/parser/expression/columnref_expression.cpp +3 -12
- package/src/duckdb/src/parser/expression/comparison_expression.cpp +3 -13
- package/src/duckdb/src/parser/expression/conjunction_expression.cpp +0 -12
- package/src/duckdb/src/parser/expression/constant_expression.cpp +3 -11
- package/src/duckdb/src/parser/expression/default_expression.cpp +0 -4
- package/src/duckdb/src/parser/expression/function_expression.cpp +3 -32
- package/src/duckdb/src/parser/expression/lambda_expression.cpp +4 -14
- package/src/duckdb/src/parser/expression/operator_expression.cpp +0 -12
- package/src/duckdb/src/parser/expression/parameter_expression.cpp +7 -19
- package/src/duckdb/src/parser/expression/positional_reference_expression.cpp +4 -11
- package/src/duckdb/src/parser/expression/star_expression.cpp +0 -19
- package/src/duckdb/src/parser/expression/subquery_expression.cpp +0 -18
- package/src/duckdb/src/parser/expression/window_expression.cpp +3 -39
- package/src/duckdb/src/parser/parsed_data/alter_info.cpp +5 -2
- package/src/duckdb/src/parser/parsed_data/alter_table_info.cpp +38 -0
- package/src/duckdb/src/parser/parsed_data/create_index_info.cpp +17 -1
- package/src/duckdb/src/parser/parsed_data/create_sequence_info.cpp +2 -0
- package/src/duckdb/src/parser/parsed_data/detach_info.cpp +1 -1
- package/src/duckdb/src/parser/parsed_data/drop_info.cpp +1 -1
- package/src/duckdb/src/parser/parsed_data/sample_options.cpp +0 -18
- package/src/duckdb/src/parser/parsed_data/transaction_info.cpp +4 -1
- package/src/duckdb/src/parser/parsed_data/vacuum_info.cpp +1 -1
- package/src/duckdb/src/parser/parsed_expression.cpp +0 -70
- package/src/duckdb/src/parser/parsed_expression_iterator.cpp +7 -0
- package/src/duckdb/src/parser/parser.cpp +62 -36
- package/src/duckdb/src/parser/query_node/cte_node.cpp +58 -0
- package/src/duckdb/src/parser/query_node/recursive_cte_node.cpp +0 -19
- package/src/duckdb/src/parser/query_node/select_node.cpp +0 -29
- package/src/duckdb/src/parser/query_node/set_operation_node.cpp +0 -15
- package/src/duckdb/src/parser/query_node.cpp +15 -47
- package/src/duckdb/src/parser/result_modifier.cpp +0 -87
- package/src/duckdb/src/parser/statement/execute_statement.cpp +2 -2
- package/src/duckdb/src/parser/statement/select_statement.cpp +0 -10
- package/src/duckdb/src/parser/tableref/basetableref.cpp +0 -19
- package/src/duckdb/src/parser/tableref/emptytableref.cpp +0 -4
- package/src/duckdb/src/parser/tableref/expressionlistref.cpp +0 -15
- package/src/duckdb/src/parser/tableref/joinref.cpp +3 -23
- package/src/duckdb/src/parser/tableref/pivotref.cpp +6 -45
- package/src/duckdb/src/parser/tableref/subqueryref.cpp +3 -13
- package/src/duckdb/src/parser/tableref/table_function.cpp +0 -15
- package/src/duckdb/src/parser/tableref.cpp +0 -44
- package/src/duckdb/src/parser/transform/constraint/transform_constraint.cpp +55 -38
- package/src/duckdb/src/parser/transform/expression/transform_array_access.cpp +13 -4
- package/src/duckdb/src/parser/transform/expression/transform_constant.cpp +55 -3
- package/src/duckdb/src/parser/transform/expression/transform_expression.cpp +2 -0
- package/src/duckdb/src/parser/transform/expression/transform_function.cpp +3 -0
- package/src/duckdb/src/parser/transform/expression/transform_multi_assign_reference.cpp +44 -0
- package/src/duckdb/src/parser/transform/expression/transform_param_ref.cpp +45 -26
- package/src/duckdb/src/parser/transform/helpers/transform_cte.cpp +19 -1
- package/src/duckdb/src/parser/transform/helpers/transform_typename.cpp +16 -1
- package/src/duckdb/src/parser/transform/statement/transform_copy.cpp +13 -0
- package/src/duckdb/src/parser/transform/statement/transform_create_index.cpp +32 -17
- package/src/duckdb/src/parser/transform/statement/transform_create_type.cpp +1 -1
- package/src/duckdb/src/parser/transform/statement/transform_delete.cpp +6 -1
- package/src/duckdb/src/parser/transform/statement/transform_insert.cpp +6 -1
- package/src/duckdb/src/parser/transform/statement/transform_pivot_stmt.cpp +7 -2
- package/src/duckdb/src/parser/transform/statement/transform_pragma.cpp +14 -11
- package/src/duckdb/src/parser/transform/statement/transform_prepare.cpp +28 -6
- package/src/duckdb/src/parser/transform/statement/transform_select_node.cpp +11 -2
- package/src/duckdb/src/parser/transform/statement/transform_update.cpp +6 -1
- package/src/duckdb/src/parser/transformer.cpp +44 -25
- package/src/duckdb/src/planner/binder/expression/bind_macro_expression.cpp +5 -3
- package/src/duckdb/src/planner/binder/expression/bind_parameter_expression.cpp +10 -10
- package/src/duckdb/src/planner/binder/query_node/bind_cte_node.cpp +64 -0
- package/src/duckdb/src/planner/binder/query_node/plan_cte_node.cpp +26 -0
- package/src/duckdb/src/planner/binder/query_node/plan_recursive_cte_node.cpp +5 -5
- package/src/duckdb/src/planner/binder/query_node/plan_setop.cpp +4 -4
- package/src/duckdb/src/planner/binder/query_node/plan_subquery.cpp +36 -33
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +14 -52
- package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +0 -23
- package/src/duckdb/src/planner/binder/statement/bind_execute.cpp +13 -7
- package/src/duckdb/src/planner/binder/statement/bind_export.cpp +29 -4
- package/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp +24 -5
- package/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp +32 -5
- package/src/duckdb/src/planner/binder/tableref/bind_pivot.cpp +116 -50
- package/src/duckdb/src/planner/binder/tableref/plan_cteref.cpp +1 -1
- package/src/duckdb/src/planner/binder/tableref/plan_joinref.cpp +67 -31
- package/src/duckdb/src/planner/binder/tableref/plan_subqueryref.cpp +3 -3
- package/src/duckdb/src/planner/binder.cpp +44 -31
- package/src/duckdb/src/planner/expression/bound_aggregate_expression.cpp +24 -1
- package/src/duckdb/src/planner/expression/bound_between_expression.cpp +4 -0
- package/src/duckdb/src/planner/expression/bound_cast_expression.cpp +13 -8
- package/src/duckdb/src/planner/expression/bound_function_expression.cpp +22 -0
- package/src/duckdb/src/planner/expression/bound_parameter_expression.cpp +28 -20
- package/src/duckdb/src/planner/expression/bound_window_expression.cpp +48 -4
- package/src/duckdb/src/planner/expression_binder/lateral_binder.cpp +4 -31
- package/src/duckdb/src/planner/expression_binder.cpp +23 -0
- package/src/duckdb/src/planner/expression_iterator.cpp +6 -0
- package/src/duckdb/src/planner/logical_operator.cpp +19 -7
- package/src/duckdb/src/planner/logical_operator_visitor.cpp +5 -6
- package/src/duckdb/src/planner/operator/logical_comparison_join.cpp +4 -2
- package/src/duckdb/src/planner/operator/logical_copy_to_file.cpp +8 -0
- package/src/duckdb/src/planner/operator/logical_create.cpp +14 -0
- package/src/duckdb/src/planner/operator/logical_create_index.cpp +36 -7
- package/src/duckdb/src/planner/operator/logical_create_table.cpp +16 -0
- package/src/duckdb/src/planner/operator/logical_cteref.cpp +3 -1
- package/src/duckdb/src/planner/operator/logical_delete.cpp +9 -2
- package/src/duckdb/src/planner/operator/logical_dependent_join.cpp +26 -0
- package/src/duckdb/src/planner/operator/logical_distinct.cpp +13 -0
- package/src/duckdb/src/planner/operator/logical_explain.cpp +1 -1
- package/src/duckdb/src/planner/operator/logical_extension_operator.cpp +39 -0
- package/src/duckdb/src/planner/operator/logical_get.cpp +82 -4
- package/src/duckdb/src/planner/operator/logical_insert.cpp +8 -2
- package/src/duckdb/src/planner/operator/logical_materialized_cte.cpp +22 -0
- package/src/duckdb/src/planner/operator/logical_order.cpp +39 -0
- package/src/duckdb/src/planner/operator/logical_pivot.cpp +3 -0
- package/src/duckdb/src/planner/operator/logical_recursive_cte.cpp +5 -5
- package/src/duckdb/src/planner/operator/logical_sample.cpp +3 -0
- package/src/duckdb/src/planner/operator/logical_update.cpp +8 -2
- package/src/duckdb/src/planner/parsed_data/bound_create_table_info.cpp +4 -2
- package/src/duckdb/src/planner/planner.cpp +18 -7
- package/src/duckdb/src/planner/subquery/flatten_dependent_join.cpp +90 -38
- package/src/duckdb/src/planner/subquery/has_correlated_expressions.cpp +22 -7
- package/src/duckdb/src/planner/subquery/rewrite_correlated_expressions.cpp +65 -7
- package/src/duckdb/src/storage/arena_allocator.cpp +13 -2
- package/src/duckdb/src/storage/buffer/block_manager.cpp +13 -9
- package/src/duckdb/src/storage/checkpoint/row_group_writer.cpp +1 -1
- package/src/duckdb/src/storage/checkpoint/table_data_reader.cpp +3 -4
- package/src/duckdb/src/storage/checkpoint/table_data_writer.cpp +7 -7
- package/src/duckdb/src/storage/checkpoint_manager.cpp +74 -69
- package/src/duckdb/src/storage/compression/bitpacking.cpp +87 -63
- package/src/duckdb/src/storage/compression/bitpacking_hugeint.cpp +295 -0
- package/src/duckdb/src/storage/compression/fsst.cpp +1 -1
- package/src/duckdb/src/storage/compression/rle.cpp +52 -13
- package/src/duckdb/src/storage/data_table.cpp +36 -25
- package/src/duckdb/src/storage/index.cpp +4 -26
- package/src/duckdb/src/storage/local_storage.cpp +3 -4
- package/src/duckdb/src/storage/metadata/metadata_manager.cpp +267 -0
- package/src/duckdb/src/storage/metadata/metadata_reader.cpp +80 -0
- package/src/duckdb/src/storage/metadata/metadata_writer.cpp +86 -0
- package/src/duckdb/src/storage/serialization/serialize_constraint.cpp +98 -0
- package/src/duckdb/src/storage/serialization/serialize_create_info.cpp +194 -0
- package/src/duckdb/src/storage/serialization/serialize_expression.cpp +283 -0
- package/src/duckdb/src/storage/serialization/serialize_logical_operator.cpp +762 -0
- package/src/duckdb/src/storage/serialization/serialize_macro_function.cpp +62 -0
- package/src/duckdb/src/storage/serialization/serialize_nodes.cpp +432 -0
- package/src/duckdb/src/storage/serialization/serialize_parse_info.cpp +419 -0
- package/src/duckdb/src/storage/serialization/serialize_parsed_expression.cpp +342 -0
- package/src/duckdb/src/storage/serialization/serialize_query_node.cpp +122 -0
- package/src/duckdb/src/storage/serialization/serialize_result_modifier.cpp +97 -0
- package/src/duckdb/src/storage/serialization/serialize_statement.cpp +22 -0
- package/src/duckdb/src/storage/serialization/serialize_table_filter.cpp +97 -0
- package/src/duckdb/src/storage/serialization/serialize_tableref.cpp +164 -0
- package/src/duckdb/src/storage/serialization/serialize_types.cpp +127 -0
- package/src/duckdb/src/storage/single_file_block_manager.cpp +69 -51
- package/src/duckdb/src/storage/statistics/string_stats.cpp +21 -2
- package/src/duckdb/src/storage/storage_info.cpp +3 -2
- package/src/duckdb/src/storage/storage_manager.cpp +11 -5
- package/src/duckdb/src/storage/table/chunk_info.cpp +17 -0
- package/src/duckdb/src/storage/table/column_data_checkpointer.cpp +3 -3
- package/src/duckdb/src/storage/table/list_column_data.cpp +6 -3
- package/src/duckdb/src/storage/table/persistent_table_data.cpp +1 -2
- package/src/duckdb/src/storage/table/row_group.cpp +34 -19
- package/src/duckdb/src/storage/table/row_group_collection.cpp +23 -19
- package/src/duckdb/src/storage/table/update_segment.cpp +1 -1
- package/src/duckdb/src/storage/table_index_list.cpp +1 -1
- package/src/duckdb/src/storage/wal_replay.cpp +24 -24
- package/src/duckdb/src/storage/write_ahead_log.cpp +3 -2
- package/src/duckdb/src/verification/prepared_statement_verifier.cpp +16 -11
- package/src/duckdb/third_party/concurrentqueue/concurrentqueue.h +2 -2
- package/src/duckdb/third_party/concurrentqueue/lightweightsemaphore.h +5 -2
- package/src/duckdb/third_party/fast_float/fast_float/fast_float.h +2 -0
- package/src/duckdb/third_party/httplib/httplib.hpp +10 -1
- package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +10 -0
- package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +2 -1
- package/src/duckdb/third_party/libpg_query/pg_functions.cpp +13 -0
- package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +11057 -10328
- package/src/duckdb/third_party/libpg_query/src_backend_parser_scansup.cpp +9 -0
- package/src/duckdb/third_party/mbedtls/include/mbedtls_wrapper.hpp +10 -0
- package/src/duckdb/third_party/mbedtls/mbedtls_wrapper.cpp +31 -1
- package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
- package/src/duckdb/ub_src_common.cpp +4 -0
- package/src/duckdb/ub_src_common_adbc_nanoarrow.cpp +8 -0
- package/src/duckdb/ub_src_common_arrow_appender.cpp +10 -0
- package/src/duckdb/ub_src_common_serializer.cpp +2 -0
- package/src/duckdb/ub_src_core_functions_scalar_debug.cpp +2 -0
- package/src/duckdb/ub_src_core_functions_scalar_string.cpp +2 -0
- package/src/duckdb/ub_src_execution.cpp +2 -0
- package/src/duckdb/ub_src_execution_index_art.cpp +0 -6
- package/src/duckdb/ub_src_execution_operator_persistent.cpp +2 -0
- package/src/duckdb/ub_src_execution_operator_schema.cpp +1 -1
- package/src/duckdb/ub_src_execution_operator_set.cpp +2 -0
- package/src/duckdb/ub_src_execution_physical_plan.cpp +2 -0
- package/src/duckdb/ub_src_function_scalar.cpp +2 -0
- package/src/duckdb/ub_src_function_scalar_compressed_materialization.cpp +4 -0
- package/src/duckdb/ub_src_function_scalar_list.cpp +2 -0
- package/src/duckdb/ub_src_function_table_arrow.cpp +2 -0
- package/src/duckdb/ub_src_main.cpp +2 -0
- package/src/duckdb/ub_src_main_chunk_scan_state.cpp +2 -0
- package/src/duckdb/ub_src_optimizer.cpp +6 -0
- package/src/duckdb/ub_src_optimizer_compressed_materialization.cpp +6 -0
- package/src/duckdb/ub_src_optimizer_join_order.cpp +10 -0
- package/src/duckdb/ub_src_optimizer_statistics_expression.cpp +0 -2
- package/src/duckdb/ub_src_parser.cpp +0 -2
- package/src/duckdb/ub_src_parser_query_node.cpp +2 -0
- package/src/duckdb/ub_src_parser_transform_expression.cpp +2 -0
- package/src/duckdb/ub_src_planner_binder_query_node.cpp +4 -0
- package/src/duckdb/ub_src_planner_operator.cpp +3 -3
- package/src/duckdb/ub_src_storage.cpp +0 -4
- package/src/duckdb/ub_src_storage_compression.cpp +2 -0
- package/src/duckdb/ub_src_storage_metadata.cpp +6 -0
- package/src/duckdb/ub_src_storage_serialization.cpp +28 -0
- package/src/duckdb_node.hpp +1 -0
- package/src/statement.cpp +10 -5
- package/test/columns.test.ts +25 -3
- package/test/extension.test.ts +1 -1
- package/test/test_all_types.test.ts +234 -0
- package/tsconfig.json +1 -0
- package/src/duckdb/src/execution/index/art/leaf_segment.cpp +0 -52
- package/src/duckdb/src/execution/index/art/prefix_segment.cpp +0 -42
- package/src/duckdb/src/execution/index/art/swizzleable_pointer.cpp +0 -22
- package/src/duckdb/src/execution/operator/schema/physical_create_index.cpp +0 -193
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_options.hpp +0 -25
- package/src/duckdb/src/include/duckdb/execution/index/art/leaf_segment.hpp +0 -38
- package/src/duckdb/src/include/duckdb/execution/index/art/prefix_segment.hpp +0 -40
- package/src/duckdb/src/include/duckdb/execution/index/art/swizzleable_pointer.hpp +0 -58
- package/src/duckdb/src/include/duckdb/planner/operator/logical_asof_join.hpp +0 -27
- package/src/duckdb/src/include/duckdb/planner/operator/logical_delim_join.hpp +0 -32
- package/src/duckdb/src/include/duckdb/storage/meta_block_reader.hpp +0 -49
- package/src/duckdb/src/include/duckdb/storage/meta_block_writer.hpp +0 -50
- package/src/duckdb/src/optimizer/statistics/expression/propagate_and_compress.cpp +0 -118
- package/src/duckdb/src/parser/common_table_expression_info.cpp +0 -19
- package/src/duckdb/src/planner/operator/logical_asof_join.cpp +0 -14
- package/src/duckdb/src/planner/operator/logical_delim_join.cpp +0 -27
- package/src/duckdb/src/storage/meta_block_reader.cpp +0 -78
- package/src/duckdb/src/storage/meta_block_writer.cpp +0 -80
@@ -1,4 +1,6 @@
|
|
1
1
|
#include "duckdb/optimizer/join_order/join_order_optimizer.hpp"
|
2
|
+
#include "duckdb/optimizer/join_order/cost_model.hpp"
|
3
|
+
#include "duckdb/optimizer/join_order/plan_enumerator.hpp"
|
2
4
|
|
3
5
|
#include "duckdb/common/limits.hpp"
|
4
6
|
#include "duckdb/common/pair.hpp"
|
@@ -9,1077 +11,76 @@
|
|
9
11
|
#include <algorithm>
|
10
12
|
#include <cmath>
|
11
13
|
|
12
|
-
namespace std {
|
13
|
-
|
14
|
-
//! A JoinNode is defined by the relations it joins.
|
15
|
-
template <>
|
16
|
-
struct hash<duckdb::JoinNode> {
|
17
|
-
inline string operator()(const duckdb::JoinNode &join_node) const {
|
18
|
-
return join_node.set.ToString();
|
19
|
-
}
|
20
|
-
};
|
21
|
-
} // namespace std
|
22
|
-
|
23
14
|
namespace duckdb {
|
24
15
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
return b.find(entry) == b.end();
|
30
|
-
});
|
31
|
-
}
|
32
|
-
|
33
|
-
//! Extract the set of relations referred to inside an expression
|
34
|
-
bool JoinOrderOptimizer::ExtractBindings(Expression &expression, unordered_set<idx_t> &bindings) {
|
35
|
-
if (expression.type == ExpressionType::BOUND_COLUMN_REF) {
|
36
|
-
auto &colref = expression.Cast<BoundColumnRefExpression>();
|
37
|
-
D_ASSERT(colref.depth == 0);
|
38
|
-
D_ASSERT(colref.binding.table_index != DConstants::INVALID_INDEX);
|
39
|
-
// map the base table index to the relation index used by the JoinOrderOptimizer
|
40
|
-
D_ASSERT(relation_mapping.find(colref.binding.table_index) != relation_mapping.end());
|
41
|
-
auto catalog_table = relation_mapping[colref.binding.table_index];
|
42
|
-
auto column_index = colref.binding.column_index;
|
43
|
-
cardinality_estimator.AddColumnToRelationMap(catalog_table, column_index);
|
44
|
-
bindings.insert(relation_mapping[colref.binding.table_index]);
|
45
|
-
}
|
46
|
-
if (expression.type == ExpressionType::BOUND_REF) {
|
47
|
-
// bound expression
|
48
|
-
bindings.clear();
|
49
|
-
return false;
|
50
|
-
}
|
51
|
-
D_ASSERT(expression.type != ExpressionType::SUBQUERY);
|
52
|
-
bool can_reorder = true;
|
53
|
-
ExpressionIterator::EnumerateChildren(expression, [&](Expression &expr) {
|
54
|
-
if (!ExtractBindings(expr, bindings)) {
|
55
|
-
can_reorder = false;
|
56
|
-
return;
|
57
|
-
}
|
58
|
-
});
|
59
|
-
return can_reorder;
|
60
|
-
}
|
61
|
-
|
62
|
-
void JoinOrderOptimizer::GetColumnBinding(Expression &expression, ColumnBinding &binding) {
|
63
|
-
if (expression.type == ExpressionType::BOUND_COLUMN_REF) {
|
64
|
-
// Here you have a filter on a single column in a table. Return a binding for the column
|
65
|
-
// being filtered on so the filter estimator knows what HLL count to pull
|
66
|
-
auto &colref = expression.Cast<BoundColumnRefExpression>();
|
67
|
-
D_ASSERT(colref.depth == 0);
|
68
|
-
D_ASSERT(colref.binding.table_index != DConstants::INVALID_INDEX);
|
69
|
-
// map the base table index to the relation index used by the JoinOrderOptimizer
|
70
|
-
D_ASSERT(relation_mapping.find(colref.binding.table_index) != relation_mapping.end());
|
71
|
-
binding = ColumnBinding(relation_mapping[colref.binding.table_index], colref.binding.column_index);
|
72
|
-
}
|
73
|
-
// TODO: handle inequality filters with functions.
|
74
|
-
ExpressionIterator::EnumerateChildren(expression, [&](Expression &expr) { GetColumnBinding(expr, binding); });
|
75
|
-
}
|
76
|
-
|
77
|
-
static unique_ptr<LogicalOperator> PushFilter(unique_ptr<LogicalOperator> node, unique_ptr<Expression> expr) {
|
78
|
-
// push an expression into a filter
|
79
|
-
// first check if we have any filter to push it into
|
80
|
-
if (node->type != LogicalOperatorType::LOGICAL_FILTER) {
|
81
|
-
// we don't, we need to create one
|
82
|
-
auto filter = make_uniq<LogicalFilter>();
|
83
|
-
filter->children.push_back(std::move(node));
|
84
|
-
node = std::move(filter);
|
85
|
-
}
|
86
|
-
// push the filter into the LogicalFilter
|
87
|
-
D_ASSERT(node->type == LogicalOperatorType::LOGICAL_FILTER);
|
88
|
-
auto &filter = node->Cast<LogicalFilter>();
|
89
|
-
filter.expressions.push_back(std::move(expr));
|
90
|
-
return node;
|
91
|
-
}
|
92
|
-
|
93
|
-
bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op,
|
94
|
-
vector<reference<LogicalOperator>> &filter_operators,
|
95
|
-
optional_ptr<LogicalOperator> parent) {
|
96
|
-
LogicalOperator *op = &input_op;
|
97
|
-
while (op->children.size() == 1 &&
|
98
|
-
(op->type != LogicalOperatorType::LOGICAL_PROJECTION &&
|
99
|
-
op->type != LogicalOperatorType::LOGICAL_EXPRESSION_GET && op->type != LogicalOperatorType::LOGICAL_GET)) {
|
100
|
-
if (op->type == LogicalOperatorType::LOGICAL_FILTER) {
|
101
|
-
// extract join conditions from filter
|
102
|
-
filter_operators.push_back(*op);
|
103
|
-
}
|
104
|
-
if (op->type == LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY ||
|
105
|
-
op->type == LogicalOperatorType::LOGICAL_WINDOW) {
|
106
|
-
// don't push filters through projection or aggregate and group by
|
107
|
-
JoinOrderOptimizer optimizer(context);
|
108
|
-
op->children[0] = optimizer.Optimize(std::move(op->children[0]));
|
109
|
-
return false;
|
110
|
-
}
|
111
|
-
op = op->children[0].get();
|
112
|
-
}
|
113
|
-
bool non_reorderable_operation = false;
|
114
|
-
if (op->type == LogicalOperatorType::LOGICAL_UNION || op->type == LogicalOperatorType::LOGICAL_EXCEPT ||
|
115
|
-
op->type == LogicalOperatorType::LOGICAL_INTERSECT || op->type == LogicalOperatorType::LOGICAL_DELIM_JOIN ||
|
116
|
-
op->type == LogicalOperatorType::LOGICAL_ANY_JOIN || op->type == LogicalOperatorType::LOGICAL_ASOF_JOIN) {
|
117
|
-
// set operation, optimize separately in children
|
118
|
-
non_reorderable_operation = true;
|
119
|
-
}
|
120
|
-
|
121
|
-
if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) {
|
122
|
-
auto &join = op->Cast<LogicalComparisonJoin>();
|
123
|
-
if (join.join_type == JoinType::INNER) {
|
124
|
-
// extract join conditions from inner join
|
125
|
-
filter_operators.push_back(*op);
|
126
|
-
} else {
|
127
|
-
// non-inner join, not reorderable yet
|
128
|
-
non_reorderable_operation = true;
|
129
|
-
if (join.join_type == JoinType::LEFT && join.right_projection_map.empty()) {
|
130
|
-
// for left joins; if the RHS cardinality is significantly larger than the LHS (2x)
|
131
|
-
// we convert to doing a RIGHT OUTER JOIN
|
132
|
-
// FIXME: for now we don't swap if the right_projection_map is not empty
|
133
|
-
// this can be fixed once we implement the left_projection_map properly...
|
134
|
-
auto lhs_cardinality = join.children[0]->EstimateCardinality(context);
|
135
|
-
auto rhs_cardinality = join.children[1]->EstimateCardinality(context);
|
136
|
-
if (rhs_cardinality > lhs_cardinality * 2) {
|
137
|
-
join.join_type = JoinType::RIGHT;
|
138
|
-
std::swap(join.children[0], join.children[1]);
|
139
|
-
for (auto &cond : join.conditions) {
|
140
|
-
std::swap(cond.left, cond.right);
|
141
|
-
cond.comparison = FlipComparisonExpression(cond.comparison);
|
142
|
-
}
|
143
|
-
}
|
144
|
-
}
|
16
|
+
static bool HasJoin(LogicalOperator *op) {
|
17
|
+
while (!op->children.empty()) {
|
18
|
+
if (op->children.size() == 1) {
|
19
|
+
op = op->children[0].get();
|
145
20
|
}
|
146
|
-
|
147
|
-
if (op->type == LogicalOperatorType::LOGICAL_ANY_JOIN && non_reorderable_operation) {
|
148
|
-
auto &join = op->Cast<LogicalAnyJoin>();
|
149
|
-
if (join.join_type == JoinType::LEFT && join.right_projection_map.empty()) {
|
150
|
-
auto lhs_cardinality = join.children[0]->EstimateCardinality(context);
|
151
|
-
auto rhs_cardinality = join.children[1]->EstimateCardinality(context);
|
152
|
-
if (rhs_cardinality > lhs_cardinality * 2) {
|
153
|
-
join.join_type = JoinType::RIGHT;
|
154
|
-
std::swap(join.children[0], join.children[1]);
|
155
|
-
}
|
156
|
-
}
|
157
|
-
}
|
158
|
-
|
159
|
-
if (non_reorderable_operation) {
|
160
|
-
// we encountered a non-reordable operation (setop or non-inner join)
|
161
|
-
// we do not reorder non-inner joins yet, however we do want to expand the potential join graph around them
|
162
|
-
// non-inner joins are also tricky because we can't freely make conditions through them
|
163
|
-
// e.g. suppose we have (left LEFT OUTER JOIN right WHERE right IS NOT NULL), the join can generate
|
164
|
-
// new NULL values in the right side, so pushing this condition through the join leads to incorrect results
|
165
|
-
// for this reason, we just start a new JoinOptimizer pass in each of the children of the join
|
166
|
-
|
167
|
-
// Keep track of all filter bindings the new join order optimizer makes
|
168
|
-
vector<column_binding_map_t<ColumnBinding>> child_binding_maps;
|
169
|
-
idx_t child_bindings_it = 0;
|
170
|
-
for (auto &child : op->children) {
|
171
|
-
child_binding_maps.emplace_back();
|
172
|
-
JoinOrderOptimizer optimizer(context);
|
173
|
-
child = optimizer.Optimize(std::move(child));
|
174
|
-
// save the relation bindings from the optimized child. These later all get added to the
|
175
|
-
// parent cardinality_estimator relation column binding map.
|
176
|
-
optimizer.cardinality_estimator.CopyRelationMap(child_binding_maps.at(child_bindings_it));
|
177
|
-
child_bindings_it += 1;
|
178
|
-
}
|
179
|
-
// after this we want to treat this node as one "end node" (like e.g. a base relation)
|
180
|
-
// however the join refers to multiple base relations
|
181
|
-
// enumerate all base relations obtained from this join and add them to the relation mapping
|
182
|
-
// also, we have to resolve the join conditions for the joins here
|
183
|
-
// get the left and right bindings
|
184
|
-
unordered_set<idx_t> bindings;
|
185
|
-
LogicalJoin::GetTableReferences(*op, bindings);
|
186
|
-
// now create the relation that refers to all these bindings
|
187
|
-
auto relation = make_uniq<SingleJoinRelation>(input_op, parent);
|
188
|
-
auto relation_id = relations.size();
|
189
|
-
// Add binding information from the nonreorderable join to this relation.
|
190
|
-
for (idx_t it : bindings) {
|
191
|
-
cardinality_estimator.MergeBindings(it, relation_id, child_binding_maps);
|
192
|
-
relation_mapping[it] = relation_id;
|
193
|
-
}
|
194
|
-
relations.push_back(std::move(relation));
|
195
|
-
return true;
|
196
|
-
}
|
197
|
-
|
198
|
-
switch (op->type) {
|
199
|
-
case LogicalOperatorType::LOGICAL_ASOF_JOIN:
|
200
|
-
case LogicalOperatorType::LOGICAL_COMPARISON_JOIN:
|
201
|
-
case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: {
|
202
|
-
// inner join or cross product
|
203
|
-
bool can_reorder_left = ExtractJoinRelations(*op->children[0], filter_operators, op);
|
204
|
-
bool can_reorder_right = ExtractJoinRelations(*op->children[1], filter_operators, op);
|
205
|
-
return can_reorder_left && can_reorder_right;
|
206
|
-
}
|
207
|
-
case LogicalOperatorType::LOGICAL_EXPRESSION_GET: {
|
208
|
-
// base table scan, add to set of relations
|
209
|
-
auto &get = op->Cast<LogicalExpressionGet>();
|
210
|
-
auto relation = make_uniq<SingleJoinRelation>(input_op, parent);
|
211
|
-
//! make sure the optimizer has knowledge of the exact column bindings as well.
|
212
|
-
relation_mapping[get.table_index] = relations.size();
|
213
|
-
relations.push_back(std::move(relation));
|
214
|
-
return true;
|
215
|
-
}
|
216
|
-
case LogicalOperatorType::LOGICAL_DUMMY_SCAN: {
|
217
|
-
// table function call, add to set of relations
|
218
|
-
auto &dummy_scan = op->Cast<LogicalDummyScan>();
|
219
|
-
auto relation = make_uniq<SingleJoinRelation>(input_op, parent);
|
220
|
-
relation_mapping[dummy_scan.table_index] = relations.size();
|
221
|
-
relations.push_back(std::move(relation));
|
222
|
-
return true;
|
223
|
-
}
|
224
|
-
case LogicalOperatorType::LOGICAL_GET:
|
225
|
-
case LogicalOperatorType::LOGICAL_PROJECTION: {
|
226
|
-
auto table_index = op->GetTableIndex()[0];
|
227
|
-
auto relation = make_uniq<SingleJoinRelation>(input_op, parent);
|
228
|
-
auto relation_id = relations.size();
|
229
|
-
|
230
|
-
// If the children are empty, operator can't ge a logical get.
|
231
|
-
if (op->children.empty() && op->type == LogicalOperatorType::LOGICAL_GET) {
|
232
|
-
auto &get = op->Cast<LogicalGet>();
|
233
|
-
cardinality_estimator.AddRelationColumnMapping(get, relation_id);
|
234
|
-
relation_mapping[table_index] = relation_id;
|
235
|
-
relations.push_back(std::move(relation));
|
21
|
+
if (op->children.size() == 2) {
|
236
22
|
return true;
|
237
23
|
}
|
238
|
-
|
239
|
-
// we run the join order optimizer within the subquery as well
|
240
|
-
JoinOrderOptimizer optimizer(context);
|
241
|
-
op->children[0] = optimizer.Optimize(std::move(op->children[0]));
|
242
|
-
// push one child column binding map back.
|
243
|
-
vector<column_binding_map_t<ColumnBinding>> child_binding_maps;
|
244
|
-
child_binding_maps.emplace_back();
|
245
|
-
optimizer.cardinality_estimator.CopyRelationMap(child_binding_maps.at(0));
|
246
|
-
// This logical projection/get may sit on top of a logical comparison join that has been pushed down
|
247
|
-
// we want to copy the binding info of both tables
|
248
|
-
relation_mapping[table_index] = relation_id;
|
249
|
-
for (auto &binding_info : child_binding_maps.at(0)) {
|
250
|
-
cardinality_estimator.AddRelationToColumnMapping(
|
251
|
-
ColumnBinding(table_index, binding_info.first.column_index), binding_info.second);
|
252
|
-
cardinality_estimator.AddColumnToRelationMap(binding_info.second.table_index,
|
253
|
-
binding_info.second.column_index);
|
254
|
-
}
|
255
|
-
relations.push_back(std::move(relation));
|
256
|
-
return true;
|
257
|
-
}
|
258
|
-
default:
|
259
|
-
return false;
|
260
|
-
}
|
261
|
-
}
|
262
|
-
|
263
|
-
//! Update the exclusion set with all entries in the subgraph
|
264
|
-
static void UpdateExclusionSet(JoinRelationSet &node, unordered_set<idx_t> &exclusion_set) {
|
265
|
-
for (idx_t i = 0; i < node.count; i++) {
|
266
|
-
exclusion_set.insert(node.relations[i]);
|
267
|
-
}
|
268
|
-
}
|
269
|
-
|
270
|
-
//! Create a new JoinTree node by joining together two previous JoinTree nodes
|
271
|
-
unique_ptr<JoinNode> JoinOrderOptimizer::CreateJoinTree(JoinRelationSet &set,
|
272
|
-
const vector<reference<NeighborInfo>> &possible_connections,
|
273
|
-
JoinNode &left, JoinNode &right) {
|
274
|
-
// for the hash join we want the right side (build side) to have the smallest cardinality
|
275
|
-
// also just a heuristic but for now...
|
276
|
-
// FIXME: we should probably actually benchmark that as well
|
277
|
-
// FIXME: should consider different join algorithms, should we pick a join algorithm here as well? (probably)
|
278
|
-
double expected_cardinality;
|
279
|
-
optional_ptr<NeighborInfo> best_connection;
|
280
|
-
auto plan = plans.find(&set);
|
281
|
-
// if we have already calculated an expected cardinality for this set,
|
282
|
-
// just re-use that cardinality
|
283
|
-
if (left.GetCardinality<double>() < right.GetCardinality<double>()) {
|
284
|
-
return CreateJoinTree(set, possible_connections, right, left);
|
285
|
-
}
|
286
|
-
if (plan != plans.end()) {
|
287
|
-
if (!plan->second) {
|
288
|
-
throw InternalException("No plan: internal error in join order optimizer");
|
289
|
-
}
|
290
|
-
expected_cardinality = plan->second->GetCardinality<double>();
|
291
|
-
best_connection = &possible_connections.back().get();
|
292
|
-
} else if (possible_connections.empty()) {
|
293
|
-
// cross product
|
294
|
-
expected_cardinality = cardinality_estimator.EstimateCrossProduct(left, right);
|
295
|
-
} else {
|
296
|
-
// normal join, expect foreign key join
|
297
|
-
expected_cardinality = cardinality_estimator.EstimateCardinalityWithSet(set);
|
298
|
-
best_connection = &possible_connections.back().get();
|
299
|
-
}
|
300
|
-
|
301
|
-
auto cost = CardinalityEstimator::ComputeCost(left, right, expected_cardinality);
|
302
|
-
auto result = make_uniq<JoinNode>(set, best_connection, left, right, expected_cardinality, cost);
|
303
|
-
D_ASSERT(cost >= expected_cardinality);
|
304
|
-
return result;
|
305
|
-
}
|
306
|
-
|
307
|
-
bool JoinOrderOptimizer::NodeInFullPlan(JoinNode &node) {
|
308
|
-
return join_nodes_in_full_plan.find(node.set.ToString()) != join_nodes_in_full_plan.end();
|
309
|
-
}
|
310
|
-
|
311
|
-
void JoinOrderOptimizer::UpdateJoinNodesInFullPlan(JoinNode &node) {
|
312
|
-
if (node.set.count == relations.size()) {
|
313
|
-
join_nodes_in_full_plan.clear();
|
314
|
-
}
|
315
|
-
if (node.set.count < relations.size()) {
|
316
|
-
join_nodes_in_full_plan.insert(node.set.ToString());
|
317
|
-
}
|
318
|
-
if (node.left) {
|
319
|
-
UpdateJoinNodesInFullPlan(*node.left);
|
320
|
-
}
|
321
|
-
if (node.right) {
|
322
|
-
UpdateJoinNodesInFullPlan(*node.right);
|
323
|
-
}
|
324
|
-
}
|
325
|
-
|
326
|
-
JoinNode &JoinOrderOptimizer::EmitPair(JoinRelationSet &left, JoinRelationSet &right,
|
327
|
-
const vector<reference<NeighborInfo>> &info) {
|
328
|
-
// get the left and right join plans
|
329
|
-
auto &left_plan = plans[&left];
|
330
|
-
auto &right_plan = plans[&right];
|
331
|
-
if (!left_plan || !right_plan) {
|
332
|
-
throw InternalException("No left or right plan: internal error in join order optimizer");
|
333
|
-
}
|
334
|
-
auto &new_set = set_manager.Union(left, right);
|
335
|
-
// create the join tree based on combining the two plans
|
336
|
-
auto new_plan = CreateJoinTree(new_set, info, *left_plan, *right_plan);
|
337
|
-
// check if this plan is the optimal plan we found for this set of relations
|
338
|
-
auto entry = plans.find(&new_set);
|
339
|
-
if (entry == plans.end() || new_plan->GetCost() < entry->second->GetCost()) {
|
340
|
-
// the plan is the optimal plan, move it into the dynamic programming tree
|
341
|
-
auto &result = *new_plan;
|
342
|
-
|
343
|
-
//! make sure plans are symmetric for cardinality estimation
|
344
|
-
if (entry != plans.end()) {
|
345
|
-
cardinality_estimator.VerifySymmetry(result, *entry->second);
|
346
|
-
}
|
347
|
-
if (full_plan_found &&
|
348
|
-
join_nodes_in_full_plan.find(new_plan->set.ToString()) != join_nodes_in_full_plan.end()) {
|
349
|
-
must_update_full_plan = true;
|
350
|
-
}
|
351
|
-
if (new_set.count == relations.size()) {
|
352
|
-
full_plan_found = true;
|
353
|
-
// If we find a full plan, we need to keep track of which nodes are in the full plan.
|
354
|
-
// It's possible the DP algorithm updates one of these nodes, then goes on to solve
|
355
|
-
// the order approximately. In the approximate algorithm, it's not guaranteed that the
|
356
|
-
// node references are updated. If the original full plan is determined to still have
|
357
|
-
// the lowest cost, it's possible to get use-after-free errors.
|
358
|
-
// If we know a node in the full plan is updated, we can prevent ourselves from exiting the
|
359
|
-
// DP algorithm until the last plan updated is a full plan
|
360
|
-
UpdateJoinNodesInFullPlan(result);
|
361
|
-
if (must_update_full_plan) {
|
362
|
-
must_update_full_plan = false;
|
363
|
-
}
|
364
|
-
}
|
365
|
-
|
366
|
-
D_ASSERT(new_plan);
|
367
|
-
plans[&new_set] = std::move(new_plan);
|
368
|
-
return result;
|
369
|
-
}
|
370
|
-
return *entry->second;
|
371
|
-
}
|
372
|
-
|
373
|
-
bool JoinOrderOptimizer::TryEmitPair(JoinRelationSet &left, JoinRelationSet &right,
|
374
|
-
const vector<reference<NeighborInfo>> &info) {
|
375
|
-
pairs++;
|
376
|
-
// If a full plan is created, it's possible a node in the plan gets updated. When this happens, make sure you keep
|
377
|
-
// emitting pairs until you emit another final plan. Another final plan is guaranteed to be produced because of
|
378
|
-
// our symmetry guarantees.
|
379
|
-
if (pairs >= 10000 && !must_update_full_plan) {
|
380
|
-
// when the amount of pairs gets too large we exit the dynamic programming and resort to a greedy algorithm
|
381
|
-
// FIXME: simple heuristic currently
|
382
|
-
// at 10K pairs stop searching exactly and switch to heuristic
|
383
|
-
return false;
|
384
|
-
}
|
385
|
-
EmitPair(left, right, info);
|
386
|
-
return true;
|
387
|
-
}
|
388
|
-
|
389
|
-
bool JoinOrderOptimizer::EmitCSG(JoinRelationSet &node) {
|
390
|
-
if (node.count == relations.size()) {
|
391
|
-
return true;
|
392
|
-
}
|
393
|
-
// create the exclusion set as everything inside the subgraph AND anything with members BELOW it
|
394
|
-
unordered_set<idx_t> exclusion_set;
|
395
|
-
for (idx_t i = 0; i < node.relations[0]; i++) {
|
396
|
-
exclusion_set.insert(i);
|
397
|
-
}
|
398
|
-
UpdateExclusionSet(node, exclusion_set);
|
399
|
-
// find the neighbors given this exclusion set
|
400
|
-
auto neighbors = query_graph.GetNeighbors(node, exclusion_set);
|
401
|
-
if (neighbors.empty()) {
|
402
|
-
return true;
|
403
|
-
}
|
404
|
-
|
405
|
-
//! Neighbors should be reversed when iterating over them.
|
406
|
-
std::sort(neighbors.begin(), neighbors.end(), std::greater_equal<idx_t>());
|
407
|
-
for (idx_t i = 0; i < neighbors.size() - 1; i++) {
|
408
|
-
D_ASSERT(neighbors[i] >= neighbors[i + 1]);
|
409
|
-
}
|
410
|
-
for (auto neighbor : neighbors) {
|
411
|
-
// since the GetNeighbors only returns the smallest element in a list, the entry might not be connected to
|
412
|
-
// (only!) this neighbor, hence we have to do a connectedness check before we can emit it
|
413
|
-
auto &neighbor_relation = set_manager.GetJoinRelation(neighbor);
|
414
|
-
auto connections = query_graph.GetConnections(node, neighbor_relation);
|
415
|
-
if (!connections.empty()) {
|
416
|
-
if (!TryEmitPair(node, neighbor_relation, connections)) {
|
417
|
-
return false;
|
418
|
-
}
|
419
|
-
}
|
420
|
-
if (!EnumerateCmpRecursive(node, neighbor_relation, exclusion_set)) {
|
421
|
-
return false;
|
422
|
-
}
|
423
|
-
}
|
424
|
-
return true;
|
425
|
-
}
|
426
|
-
|
427
|
-
bool JoinOrderOptimizer::EnumerateCmpRecursive(JoinRelationSet &left, JoinRelationSet &right,
|
428
|
-
unordered_set<idx_t> exclusion_set) {
|
429
|
-
// get the neighbors of the second relation under the exclusion set
|
430
|
-
auto neighbors = query_graph.GetNeighbors(right, exclusion_set);
|
431
|
-
if (neighbors.empty()) {
|
432
|
-
return true;
|
433
|
-
}
|
434
|
-
vector<reference<JoinRelationSet>> union_sets;
|
435
|
-
union_sets.reserve(neighbors.size());
|
436
|
-
for (idx_t i = 0; i < neighbors.size(); i++) {
|
437
|
-
auto &neighbor = set_manager.GetJoinRelation(neighbors[i]);
|
438
|
-
// emit the combinations of this node and its neighbors
|
439
|
-
auto &combined_set = set_manager.Union(right, neighbor);
|
440
|
-
if (combined_set.count > right.count && plans.find(&combined_set) != plans.end()) {
|
441
|
-
auto connections = query_graph.GetConnections(left, combined_set);
|
442
|
-
if (!connections.empty()) {
|
443
|
-
if (!TryEmitPair(left, combined_set, connections)) {
|
444
|
-
return false;
|
445
|
-
}
|
446
|
-
}
|
447
|
-
}
|
448
|
-
union_sets.push_back(combined_set);
|
449
|
-
}
|
450
|
-
// recursively enumerate the sets
|
451
|
-
unordered_set<idx_t> new_exclusion_set = exclusion_set;
|
452
|
-
for (idx_t i = 0; i < neighbors.size(); i++) {
|
453
|
-
// updated the set of excluded entries with this neighbor
|
454
|
-
new_exclusion_set.insert(neighbors[i]);
|
455
|
-
if (!EnumerateCmpRecursive(left, union_sets[i], new_exclusion_set)) {
|
456
|
-
return false;
|
457
|
-
}
|
458
24
|
}
|
459
|
-
return
|
25
|
+
return false;
|
460
26
|
}
|
461
27
|
|
462
|
-
|
463
|
-
|
464
|
-
auto neighbors = query_graph.GetNeighbors(node, exclusion_set);
|
465
|
-
if (neighbors.empty()) {
|
466
|
-
return true;
|
467
|
-
}
|
468
|
-
vector<reference<JoinRelationSet>> union_sets;
|
469
|
-
union_sets.reserve(neighbors.size());
|
470
|
-
for (idx_t i = 0; i < neighbors.size(); i++) {
|
471
|
-
auto &neighbor = set_manager.GetJoinRelation(neighbors[i]);
|
472
|
-
// emit the combinations of this node and its neighbors
|
473
|
-
auto &new_set = set_manager.Union(node, neighbor);
|
474
|
-
if (new_set.count > node.count && plans.find(&new_set) != plans.end()) {
|
475
|
-
if (!EmitCSG(new_set)) {
|
476
|
-
return false;
|
477
|
-
}
|
478
|
-
}
|
479
|
-
union_sets.push_back(new_set);
|
480
|
-
}
|
481
|
-
// recursively enumerate the sets
|
482
|
-
unordered_set<idx_t> new_exclusion_set = exclusion_set;
|
483
|
-
for (idx_t i = 0; i < neighbors.size(); i++) {
|
484
|
-
// Reset the exclusion set so that the algorithm considers all combinations
|
485
|
-
// of the exclusion_set with a subset of neighbors.
|
486
|
-
new_exclusion_set = exclusion_set;
|
487
|
-
new_exclusion_set.insert(neighbors[i]);
|
488
|
-
// updated the set of excluded entries with this neighbor
|
489
|
-
if (!EnumerateCSGRecursive(union_sets[i], new_exclusion_set)) {
|
490
|
-
return false;
|
491
|
-
}
|
492
|
-
}
|
493
|
-
return true;
|
494
|
-
}
|
495
|
-
|
496
|
-
bool JoinOrderOptimizer::SolveJoinOrderExactly() {
|
497
|
-
// now we perform the actual dynamic programming to compute the final result
|
498
|
-
// we enumerate over all the possible pairs in the neighborhood
|
499
|
-
for (idx_t i = relations.size(); i > 0; i--) {
|
500
|
-
// for every node in the set, we consider it as the start node once
|
501
|
-
auto &start_node = set_manager.GetJoinRelation(i - 1);
|
502
|
-
// emit the start node
|
503
|
-
if (!EmitCSG(start_node)) {
|
504
|
-
return false;
|
505
|
-
}
|
506
|
-
// initialize the set of exclusion_set as all the nodes with a number below this
|
507
|
-
unordered_set<idx_t> exclusion_set;
|
508
|
-
for (idx_t j = 0; j < i - 1; j++) {
|
509
|
-
exclusion_set.insert(j);
|
510
|
-
}
|
511
|
-
// then we recursively search for neighbors that do not belong to the banned entries
|
512
|
-
if (!EnumerateCSGRecursive(start_node, exclusion_set)) {
|
513
|
-
return false;
|
514
|
-
}
|
515
|
-
}
|
516
|
-
return true;
|
517
|
-
}
|
518
|
-
|
519
|
-
static vector<unordered_set<idx_t>> AddSuperSets(vector<unordered_set<idx_t>> current,
|
520
|
-
const vector<idx_t> &all_neighbors) {
|
521
|
-
vector<unordered_set<idx_t>> ret;
|
522
|
-
for (auto &neighbor : all_neighbors) {
|
523
|
-
for (auto &neighbor_set : current) {
|
524
|
-
auto max_val = std::max_element(neighbor_set.begin(), neighbor_set.end());
|
525
|
-
if (*max_val >= neighbor) {
|
526
|
-
continue;
|
527
|
-
}
|
528
|
-
if (neighbor_set.count(neighbor) == 0) {
|
529
|
-
unordered_set<idx_t> new_set;
|
530
|
-
for (auto &n : neighbor_set) {
|
531
|
-
new_set.insert(n);
|
532
|
-
}
|
533
|
-
new_set.insert(neighbor);
|
534
|
-
ret.push_back(new_set);
|
535
|
-
}
|
536
|
-
}
|
537
|
-
}
|
538
|
-
return ret;
|
539
|
-
}
|
540
|
-
|
541
|
-
// works by first creating all sets with cardinality 1
|
542
|
-
// then iterates over each previously created group of subsets and will only add a neighbor if the neighbor
|
543
|
-
// is greater than all relations in the set.
|
544
|
-
static vector<unordered_set<idx_t>> GetAllNeighborSets(unordered_set<idx_t> &exclusion_set, vector<idx_t> neighbors) {
|
545
|
-
vector<unordered_set<idx_t>> ret;
|
546
|
-
sort(neighbors.begin(), neighbors.end());
|
547
|
-
vector<unordered_set<idx_t>> added;
|
548
|
-
for (auto &neighbor : neighbors) {
|
549
|
-
added.push_back(unordered_set<idx_t>({neighbor}));
|
550
|
-
ret.push_back(unordered_set<idx_t>({neighbor}));
|
551
|
-
}
|
552
|
-
do {
|
553
|
-
added = AddSuperSets(added, neighbors);
|
554
|
-
for (auto &d : added) {
|
555
|
-
ret.push_back(d);
|
556
|
-
}
|
557
|
-
} while (!added.empty());
|
558
|
-
#if DEBUG
|
559
|
-
// drive by test to make sure we have an accurate amount of
|
560
|
-
// subsets, and that each neighbor is in a correct amount
|
561
|
-
// of those subsets.
|
562
|
-
D_ASSERT(ret.size() == pow(2, neighbors.size()) - 1);
|
563
|
-
for (auto &n : neighbors) {
|
564
|
-
idx_t count = 0;
|
565
|
-
for (auto &set : ret) {
|
566
|
-
if (set.count(n) >= 1) {
|
567
|
-
count += 1;
|
568
|
-
}
|
569
|
-
}
|
570
|
-
D_ASSERT(count == pow(2, neighbors.size() - 1));
|
571
|
-
}
|
572
|
-
#endif
|
573
|
-
return ret;
|
574
|
-
}
|
575
|
-
|
576
|
-
void JoinOrderOptimizer::UpdateDPTree(JoinNode &new_plan) {
|
577
|
-
if (!NodeInFullPlan(new_plan)) {
|
578
|
-
// if the new node is not in the full plan, feel free to return
|
579
|
-
// because you won't be updating the full plan.
|
580
|
-
return;
|
581
|
-
}
|
582
|
-
auto &new_set = new_plan.set;
|
583
|
-
// now update every plan that uses this plan
|
584
|
-
unordered_set<idx_t> exclusion_set;
|
585
|
-
for (idx_t i = 0; i < new_set.count; i++) {
|
586
|
-
exclusion_set.insert(new_set.relations[i]);
|
587
|
-
}
|
588
|
-
auto neighbors = query_graph.GetNeighbors(new_set, exclusion_set);
|
589
|
-
auto all_neighbors = GetAllNeighborSets(exclusion_set, neighbors);
|
590
|
-
for (auto neighbor : all_neighbors) {
|
591
|
-
auto &neighbor_relation = set_manager.GetJoinRelation(neighbor);
|
592
|
-
auto &combined_set = set_manager.Union(new_set, neighbor_relation);
|
593
|
-
|
594
|
-
auto combined_set_plan = plans.find(&combined_set);
|
595
|
-
if (combined_set_plan == plans.end()) {
|
596
|
-
continue;
|
597
|
-
}
|
598
|
-
|
599
|
-
double combined_set_plan_cost = combined_set_plan->second->GetCost();
|
600
|
-
auto connections = query_graph.GetConnections(new_set, neighbor_relation);
|
601
|
-
// recurse and update up the tree if the combined set produces a plan with a lower cost
|
602
|
-
// only recurse on neighbor relations that have plans.
|
603
|
-
auto right_plan = plans.find(&neighbor_relation);
|
604
|
-
if (right_plan == plans.end()) {
|
605
|
-
continue;
|
606
|
-
}
|
607
|
-
auto &updated_plan = EmitPair(new_set, neighbor_relation, connections);
|
608
|
-
// <= because the child node has already been replaced. You need to
|
609
|
-
// replace the parent node as well in this case
|
610
|
-
if (updated_plan.GetCost() < combined_set_plan_cost) {
|
611
|
-
UpdateDPTree(updated_plan);
|
612
|
-
}
|
613
|
-
}
|
614
|
-
}
|
615
|
-
|
616
|
-
void JoinOrderOptimizer::SolveJoinOrderApproximately() {
|
617
|
-
// at this point, we exited the dynamic programming but did not compute the final join order because it took too
|
618
|
-
// long instead, we use a greedy heuristic to obtain a join ordering now we use Greedy Operator Ordering to
|
619
|
-
// construct the result tree first we start out with all the base relations (the to-be-joined relations)
|
620
|
-
vector<reference<JoinRelationSet>> join_relations; // T in the paper
|
621
|
-
for (idx_t i = 0; i < relations.size(); i++) {
|
622
|
-
join_relations.push_back(set_manager.GetJoinRelation(i));
|
623
|
-
}
|
624
|
-
while (join_relations.size() > 1) {
|
625
|
-
// now in every step of the algorithm, we greedily pick the join between the to-be-joined relations that has the
|
626
|
-
// smallest cost. This is O(r^2) per step, and every step will reduce the total amount of relations to-be-joined
|
627
|
-
// by 1, so the total cost is O(r^3) in the amount of relations
|
628
|
-
idx_t best_left = 0, best_right = 0;
|
629
|
-
optional_ptr<JoinNode> best_connection;
|
630
|
-
for (idx_t i = 0; i < join_relations.size(); i++) {
|
631
|
-
auto left = join_relations[i];
|
632
|
-
for (idx_t j = i + 1; j < join_relations.size(); j++) {
|
633
|
-
auto right = join_relations[j];
|
634
|
-
// check if we can connect these two relations
|
635
|
-
auto connection = query_graph.GetConnections(left, right);
|
636
|
-
if (!connection.empty()) {
|
637
|
-
// we can check the cost of this connection
|
638
|
-
auto &node = EmitPair(left, right, connection);
|
639
|
-
|
640
|
-
// update the DP tree in case a plan created by the DP algorithm uses the node
|
641
|
-
// that was potentially just updated by EmitPair. You will get a use-after-free
|
642
|
-
// error if future plans rely on the old node that was just replaced.
|
643
|
-
// if node in FullPath, then updateDP tree.
|
644
|
-
UpdateDPTree(node);
|
645
|
-
|
646
|
-
if (!best_connection || node.GetCost() < best_connection->GetCost()) {
|
647
|
-
// best pair found so far
|
648
|
-
best_connection = &node;
|
649
|
-
best_left = i;
|
650
|
-
best_right = j;
|
651
|
-
}
|
652
|
-
}
|
653
|
-
}
|
654
|
-
}
|
655
|
-
if (!best_connection) {
|
656
|
-
// could not find a connection, but we were not done with finding a completed plan
|
657
|
-
// we have to add a cross product; we add it between the two smallest relations
|
658
|
-
optional_ptr<JoinNode> smallest_plans[2];
|
659
|
-
idx_t smallest_index[2];
|
660
|
-
D_ASSERT(join_relations.size() >= 2);
|
661
|
-
|
662
|
-
// first just add the first two join relations. It doesn't matter the cost as the JOO
|
663
|
-
// will swap them on estimated cardinality anyway.
|
664
|
-
for (idx_t i = 0; i < 2; i++) {
|
665
|
-
auto current_plan = plans[&join_relations[i].get()].get();
|
666
|
-
smallest_plans[i] = current_plan;
|
667
|
-
smallest_index[i] = i;
|
668
|
-
}
|
28
|
+
unique_ptr<LogicalOperator> JoinOrderOptimizer::Optimize(unique_ptr<LogicalOperator> plan,
|
29
|
+
optional_ptr<RelationStats> stats) {
|
669
30
|
|
670
|
-
|
671
|
-
|
672
|
-
for (idx_t i = 2; i < join_relations.size(); i++) {
|
673
|
-
// get the plan for this relation
|
674
|
-
auto current_plan = plans[&join_relations[i].get()].get();
|
675
|
-
// check if the cardinality is smaller than the smallest two found so far
|
676
|
-
for (idx_t j = 0; j < 2; j++) {
|
677
|
-
if (!smallest_plans[j] ||
|
678
|
-
smallest_plans[j]->GetCardinality<double>() > current_plan->GetCardinality<double>()) {
|
679
|
-
smallest_plans[j] = current_plan;
|
680
|
-
smallest_index[j] = i;
|
681
|
-
break;
|
682
|
-
}
|
683
|
-
}
|
684
|
-
}
|
685
|
-
if (!smallest_plans[0] || !smallest_plans[1]) {
|
686
|
-
throw InternalException("Internal error in join order optimizer");
|
687
|
-
}
|
688
|
-
D_ASSERT(smallest_plans[0] && smallest_plans[1]);
|
689
|
-
D_ASSERT(smallest_index[0] != smallest_index[1]);
|
690
|
-
auto &left = smallest_plans[0]->set;
|
691
|
-
auto &right = smallest_plans[1]->set;
|
692
|
-
// create a cross product edge (i.e. edge with empty filter) between these two sets in the query graph
|
693
|
-
query_graph.CreateEdge(left, right, nullptr);
|
694
|
-
// now emit the pair and continue with the algorithm
|
695
|
-
auto connections = query_graph.GetConnections(left, right);
|
696
|
-
D_ASSERT(!connections.empty());
|
697
|
-
|
698
|
-
best_connection = &EmitPair(left, right, connections);
|
699
|
-
best_left = smallest_index[0];
|
700
|
-
best_right = smallest_index[1];
|
701
|
-
|
702
|
-
UpdateDPTree(*best_connection);
|
703
|
-
// the code below assumes best_right > best_left
|
704
|
-
if (best_left > best_right) {
|
705
|
-
std::swap(best_left, best_right);
|
706
|
-
}
|
707
|
-
}
|
708
|
-
// now update the to-be-checked pairs
|
709
|
-
// remove left and right, and add the combination
|
31
|
+
// make sure query graph manager has not extracted a relation graph already
|
32
|
+
LogicalOperator *op = plan.get();
|
710
33
|
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
join_relations.erase(join_relations.begin() + best_right);
|
715
|
-
join_relations.erase(join_relations.begin() + best_left);
|
716
|
-
join_relations.push_back(best_connection->set);
|
717
|
-
}
|
718
|
-
}
|
34
|
+
// extract the relations that go into the hyper graph.
|
35
|
+
// We optimize the children of any non-reorderable operations we come across.
|
36
|
+
bool reorderable = query_graph_manager.Build(*op);
|
719
37
|
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
// otherwise, if that times out we resort to a greedy algorithm
|
724
|
-
SolveJoinOrderApproximately();
|
725
|
-
}
|
726
|
-
}
|
38
|
+
// get relation_stats here since the reconstruction process will move all of the relations.
|
39
|
+
auto relation_stats = query_graph_manager.relation_manager.GetRelationStats();
|
40
|
+
unique_ptr<LogicalOperator> new_logical_plan = nullptr;
|
727
41
|
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
for (idx_t i = 0; i < relations.size(); i++) {
|
732
|
-
auto &left = set_manager.GetJoinRelation(i);
|
733
|
-
for (idx_t j = 0; j < relations.size(); j++) {
|
734
|
-
if (i != j) {
|
735
|
-
auto &right = set_manager.GetJoinRelation(j);
|
736
|
-
query_graph.CreateEdge(left, right, nullptr);
|
737
|
-
query_graph.CreateEdge(right, left, nullptr);
|
738
|
-
}
|
739
|
-
}
|
740
|
-
}
|
741
|
-
}
|
42
|
+
if (reorderable) {
|
43
|
+
// query graph now has filters and relations
|
44
|
+
auto cost_model = CostModel(query_graph_manager);
|
742
45
|
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
if (children[i].get() == &rel.op) {
|
747
|
-
// found it! take ownership of it from the parent
|
748
|
-
auto result = std::move(children[i]);
|
749
|
-
children.erase(children.begin() + i);
|
750
|
-
return result;
|
751
|
-
}
|
752
|
-
}
|
753
|
-
throw Exception("Could not find relation in parent node (?)");
|
754
|
-
}
|
46
|
+
// Initialize a plan enumerator.
|
47
|
+
auto plan_enumerator =
|
48
|
+
PlanEnumerator(query_graph_manager, cost_model, query_graph_manager.GetQueryGraphEdges());
|
755
49
|
|
756
|
-
|
757
|
-
|
758
|
-
optional_ptr<JoinRelationSet> left_node;
|
759
|
-
optional_ptr<JoinRelationSet> right_node;
|
760
|
-
optional_ptr<JoinRelationSet> result_relation;
|
761
|
-
unique_ptr<LogicalOperator> result_operator;
|
762
|
-
if (node.left && node.right && node.info) {
|
763
|
-
// generate the left and right children
|
764
|
-
auto left = GenerateJoins(extracted_relations, *node.left);
|
765
|
-
auto right = GenerateJoins(extracted_relations, *node.right);
|
50
|
+
// Initialize the leaf/single node plans
|
51
|
+
plan_enumerator.InitLeafPlans();
|
766
52
|
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
} else {
|
771
|
-
// we have filters, create a join node
|
772
|
-
auto join = make_uniq<LogicalComparisonJoin>(JoinType::INNER);
|
773
|
-
join->children.push_back(std::move(left.op));
|
774
|
-
join->children.push_back(std::move(right.op));
|
775
|
-
// set the join conditions from the join node
|
776
|
-
for (auto &filter_ref : node.info->filters) {
|
777
|
-
auto &f = filter_ref.get();
|
778
|
-
// extract the filter from the operator it originally belonged to
|
779
|
-
D_ASSERT(filters[f.filter_index]);
|
780
|
-
auto condition = std::move(filters[f.filter_index]);
|
781
|
-
// now create the actual join condition
|
782
|
-
D_ASSERT((JoinRelationSet::IsSubset(left.set, *f.left_set) &&
|
783
|
-
JoinRelationSet::IsSubset(right.set, *f.right_set)) ||
|
784
|
-
(JoinRelationSet::IsSubset(left.set, *f.right_set) &&
|
785
|
-
JoinRelationSet::IsSubset(right.set, *f.left_set)));
|
786
|
-
JoinCondition cond;
|
787
|
-
D_ASSERT(condition->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON);
|
788
|
-
auto &comparison = condition->Cast<BoundComparisonExpression>();
|
789
|
-
// we need to figure out which side is which by looking at the relations available to us
|
790
|
-
bool invert = !JoinRelationSet::IsSubset(left.set, *f.left_set);
|
791
|
-
cond.left = !invert ? std::move(comparison.left) : std::move(comparison.right);
|
792
|
-
cond.right = !invert ? std::move(comparison.right) : std::move(comparison.left);
|
793
|
-
cond.comparison = condition->type;
|
53
|
+
// Ask the plan enumerator to enumerate a number of join orders
|
54
|
+
auto final_plan = plan_enumerator.SolveJoinOrder();
|
55
|
+
// TODO: add in the check that if no plan exists, you have to add a cross product.
|
794
56
|
|
795
|
-
|
796
|
-
|
797
|
-
cond.comparison = FlipComparisonExpression(cond.comparison);
|
798
|
-
}
|
799
|
-
join->conditions.push_back(std::move(cond));
|
800
|
-
}
|
801
|
-
D_ASSERT(!join->conditions.empty());
|
802
|
-
result_operator = std::move(join);
|
803
|
-
}
|
804
|
-
left_node = &left.set;
|
805
|
-
right_node = &right.set;
|
806
|
-
right_node = &right.set;
|
807
|
-
result_relation = &set_manager.Union(*left_node, *right_node);
|
57
|
+
// now reconstruct a logical plan from the query graph plan
|
58
|
+
new_logical_plan = query_graph_manager.Reconstruct(std::move(plan), *final_plan);
|
808
59
|
} else {
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
result_relation = &node.set;
|
813
|
-
result_operator = std::move(extracted_relations[node.set.relations[0]]);
|
814
|
-
}
|
815
|
-
result_operator->estimated_props = node.estimated_props->Copy();
|
816
|
-
result_operator->estimated_cardinality = result_operator->estimated_props->GetCardinality<idx_t>();
|
817
|
-
result_operator->has_estimated_cardinality = true;
|
818
|
-
if (result_operator->type == LogicalOperatorType::LOGICAL_FILTER &&
|
819
|
-
result_operator->children[0]->type == LogicalOperatorType::LOGICAL_GET) {
|
820
|
-
// FILTER on top of GET, add estimated properties to both
|
821
|
-
auto &filter_props = *result_operator->estimated_props;
|
822
|
-
auto &child_operator = *result_operator->children[0];
|
823
|
-
child_operator.estimated_props = make_uniq<EstimatedProperties>(
|
824
|
-
filter_props.GetCardinality<double>() / CardinalityEstimator::DEFAULT_SELECTIVITY, filter_props.GetCost());
|
825
|
-
child_operator.estimated_cardinality = child_operator.estimated_props->GetCardinality<idx_t>();
|
826
|
-
child_operator.has_estimated_cardinality = true;
|
827
|
-
}
|
828
|
-
// check if we should do a pushdown on this node
|
829
|
-
// basically, any remaining filter that is a subset of the current relation will no longer be used in joins
|
830
|
-
// hence we should push it here
|
831
|
-
for (auto &filter_info : filter_infos) {
|
832
|
-
// check if the filter has already been extracted
|
833
|
-
auto &info = *filter_info;
|
834
|
-
if (filters[info.filter_index]) {
|
835
|
-
// now check if the filter is a subset of the current relation
|
836
|
-
// note that infos with an empty relation set are a special case and we do not push them down
|
837
|
-
if (info.set.count > 0 && JoinRelationSet::IsSubset(*result_relation, info.set)) {
|
838
|
-
auto filter = std::move(filters[info.filter_index]);
|
839
|
-
// if it is, we can push the filter
|
840
|
-
// we can push it either into a join or as a filter
|
841
|
-
// check if we are in a join or in a base table
|
842
|
-
if (!left_node || !info.left_set) {
|
843
|
-
// base table or non-comparison expression, push it as a filter
|
844
|
-
result_operator = PushFilter(std::move(result_operator), std::move(filter));
|
845
|
-
continue;
|
846
|
-
}
|
847
|
-
// the node below us is a join or cross product and the expression is a comparison
|
848
|
-
// check if the nodes can be split up into left/right
|
849
|
-
bool found_subset = false;
|
850
|
-
bool invert = false;
|
851
|
-
if (JoinRelationSet::IsSubset(*left_node, *info.left_set) &&
|
852
|
-
JoinRelationSet::IsSubset(*right_node, *info.right_set)) {
|
853
|
-
found_subset = true;
|
854
|
-
} else if (JoinRelationSet::IsSubset(*right_node, *info.left_set) &&
|
855
|
-
JoinRelationSet::IsSubset(*left_node, *info.right_set)) {
|
856
|
-
invert = true;
|
857
|
-
found_subset = true;
|
858
|
-
}
|
859
|
-
if (!found_subset) {
|
860
|
-
// could not be split up into left/right
|
861
|
-
result_operator = PushFilter(std::move(result_operator), std::move(filter));
|
862
|
-
continue;
|
863
|
-
}
|
864
|
-
// create the join condition
|
865
|
-
JoinCondition cond;
|
866
|
-
D_ASSERT(filter->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON);
|
867
|
-
auto &comparison = filter->Cast<BoundComparisonExpression>();
|
868
|
-
// we need to figure out which side is which by looking at the relations available to us
|
869
|
-
cond.left = !invert ? std::move(comparison.left) : std::move(comparison.right);
|
870
|
-
cond.right = !invert ? std::move(comparison.right) : std::move(comparison.left);
|
871
|
-
cond.comparison = comparison.type;
|
872
|
-
if (invert) {
|
873
|
-
// reverse comparison expression if we reverse the order of the children
|
874
|
-
cond.comparison = FlipComparisonExpression(comparison.type);
|
875
|
-
}
|
876
|
-
// now find the join to push it into
|
877
|
-
auto node = result_operator.get();
|
878
|
-
if (node->type == LogicalOperatorType::LOGICAL_FILTER) {
|
879
|
-
node = node->children[0].get();
|
880
|
-
}
|
881
|
-
if (node->type == LogicalOperatorType::LOGICAL_CROSS_PRODUCT) {
|
882
|
-
// turn into comparison join
|
883
|
-
auto comp_join = make_uniq<LogicalComparisonJoin>(JoinType::INNER);
|
884
|
-
comp_join->children.push_back(std::move(node->children[0]));
|
885
|
-
comp_join->children.push_back(std::move(node->children[1]));
|
886
|
-
comp_join->conditions.push_back(std::move(cond));
|
887
|
-
if (node == result_operator.get()) {
|
888
|
-
result_operator = std::move(comp_join);
|
889
|
-
} else {
|
890
|
-
D_ASSERT(result_operator->type == LogicalOperatorType::LOGICAL_FILTER);
|
891
|
-
result_operator->children[0] = std::move(comp_join);
|
892
|
-
}
|
893
|
-
} else {
|
894
|
-
D_ASSERT(node->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN ||
|
895
|
-
node->type == LogicalOperatorType::LOGICAL_ASOF_JOIN);
|
896
|
-
auto &comp_join = node->Cast<LogicalComparisonJoin>();
|
897
|
-
comp_join.conditions.push_back(std::move(cond));
|
898
|
-
}
|
899
|
-
}
|
900
|
-
}
|
901
|
-
}
|
902
|
-
return GenerateJoinRelation(*result_relation, std::move(result_operator));
|
903
|
-
}
|
904
|
-
|
905
|
-
unique_ptr<LogicalOperator> JoinOrderOptimizer::RewritePlan(unique_ptr<LogicalOperator> plan, JoinNode &node) {
|
906
|
-
// now we have to rewrite the plan
|
907
|
-
bool root_is_join = plan->children.size() > 1;
|
908
|
-
|
909
|
-
// first we will extract all relations from the main plan
|
910
|
-
vector<unique_ptr<LogicalOperator>> extracted_relations;
|
911
|
-
extracted_relations.reserve(relations.size());
|
912
|
-
for (auto &relation : relations) {
|
913
|
-
extracted_relations.push_back(ExtractJoinRelation(*relation));
|
914
|
-
}
|
915
|
-
|
916
|
-
// now we generate the actual joins
|
917
|
-
auto join_tree = GenerateJoins(extracted_relations, node);
|
918
|
-
// perform the final pushdown of remaining filters
|
919
|
-
for (auto &filter : filters) {
|
920
|
-
// check if the filter has already been extracted
|
921
|
-
if (filter) {
|
922
|
-
// if not we need to push it
|
923
|
-
join_tree.op = PushFilter(std::move(join_tree.op), std::move(filter));
|
60
|
+
new_logical_plan = std::move(plan);
|
61
|
+
if (relation_stats.size() == 1) {
|
62
|
+
new_logical_plan->estimated_cardinality = relation_stats.at(0).cardinality;
|
924
63
|
}
|
925
64
|
}
|
926
65
|
|
927
|
-
//
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
// have to move up through the relations
|
934
|
-
auto op = plan.get();
|
935
|
-
auto parent = plan.get();
|
936
|
-
while (op->type != LogicalOperatorType::LOGICAL_CROSS_PRODUCT &&
|
937
|
-
op->type != LogicalOperatorType::LOGICAL_COMPARISON_JOIN &&
|
938
|
-
op->type != LogicalOperatorType::LOGICAL_ASOF_JOIN) {
|
939
|
-
D_ASSERT(op->children.size() == 1);
|
940
|
-
parent = op;
|
941
|
-
op = op->children[0].get();
|
942
|
-
}
|
943
|
-
// have to replace at this node
|
944
|
-
parent->children[0] = std::move(join_tree.op);
|
945
|
-
return plan;
|
946
|
-
}
|
947
|
-
|
948
|
-
// the join ordering is pretty much a straight implementation of the paper "Dynamic Programming Strikes Back" by Guido
|
949
|
-
// Moerkotte and Thomas Neumannn, see that paper for additional info/documentation bonus slides:
|
950
|
-
// https://db.in.tum.de/teaching/ws1415/queryopt/chapter3.pdf?lang=de
|
951
|
-
// FIXME: incorporate cardinality estimation into the plans, possibly by pushing samples?
|
952
|
-
unique_ptr<LogicalOperator> JoinOrderOptimizer::Optimize(unique_ptr<LogicalOperator> plan) {
|
953
|
-
D_ASSERT(filters.empty() && relations.empty()); // assert that the JoinOrderOptimizer has not been used before
|
954
|
-
LogicalOperator *op = plan.get();
|
955
|
-
// now we optimize the current plan
|
956
|
-
// we skip past until we find the first projection, we do this because the HAVING clause inserts a Filter AFTER the
|
957
|
-
// group by and this filter cannot be reordered
|
958
|
-
// extract a list of all relations that have to be joined together
|
959
|
-
// and a list of all conditions that is applied to them
|
960
|
-
vector<reference<LogicalOperator>> filter_operators;
|
961
|
-
if (!ExtractJoinRelations(*op, filter_operators)) {
|
962
|
-
// do not support reordering this type of plan
|
963
|
-
return plan;
|
964
|
-
}
|
965
|
-
if (relations.size() <= 1) {
|
966
|
-
// at most one relation, nothing to reorder
|
967
|
-
return plan;
|
66
|
+
// only perform left right optimizations when stats is null (means we have the top level optimize call)
|
67
|
+
// Don't check reorderability because non-reorderable joins will result in 1 relation, but we can
|
68
|
+
// still switch the children.
|
69
|
+
// TODO: put this in a different optimizer maybe?
|
70
|
+
if (stats == nullptr && HasJoin(new_logical_plan.get())) {
|
71
|
+
new_logical_plan = query_graph_manager.LeftRightOptimizations(std::move(new_logical_plan));
|
968
72
|
}
|
969
|
-
// now that we know we are going to perform join ordering we actually extract the filters, eliminating duplicate
|
970
|
-
// filters in the process
|
971
|
-
expression_set_t filter_set;
|
972
|
-
for (auto &filter_op : filter_operators) {
|
973
|
-
auto &f_op = filter_op.get();
|
974
|
-
if (f_op.type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN ||
|
975
|
-
f_op.type == LogicalOperatorType::LOGICAL_ASOF_JOIN) {
|
976
|
-
auto &join = f_op.Cast<LogicalComparisonJoin>();
|
977
|
-
D_ASSERT(join.join_type == JoinType::INNER);
|
978
|
-
D_ASSERT(join.expressions.empty());
|
979
|
-
for (auto &cond : join.conditions) {
|
980
|
-
auto comparison =
|
981
|
-
make_uniq<BoundComparisonExpression>(cond.comparison, std::move(cond.left), std::move(cond.right));
|
982
|
-
if (filter_set.find(*comparison) == filter_set.end()) {
|
983
|
-
filter_set.insert(*comparison);
|
984
|
-
filters.push_back(std::move(comparison));
|
985
|
-
}
|
986
|
-
}
|
987
|
-
join.conditions.clear();
|
988
|
-
} else {
|
989
|
-
for (auto &expression : f_op.expressions) {
|
990
|
-
if (filter_set.find(*expression) == filter_set.end()) {
|
991
|
-
filter_set.insert(*expression);
|
992
|
-
filters.push_back(std::move(expression));
|
993
|
-
}
|
994
|
-
}
|
995
|
-
f_op.expressions.clear();
|
996
|
-
}
|
997
|
-
}
|
998
|
-
// create potential edges from the comparisons
|
999
|
-
for (idx_t i = 0; i < filters.size(); i++) {
|
1000
|
-
auto &filter = filters[i];
|
1001
|
-
// first extract the relation set for the entire filter
|
1002
|
-
unordered_set<idx_t> bindings;
|
1003
|
-
ExtractBindings(*filter, bindings);
|
1004
|
-
auto &set = set_manager.GetJoinRelation(bindings);
|
1005
|
-
|
1006
|
-
auto info = make_uniq<FilterInfo>(set, i);
|
1007
|
-
auto filter_info = info.get();
|
1008
|
-
filter_infos.push_back(std::move(info));
|
1009
73
|
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
GetColumnBinding(*comparison.left, filter_info->left_binding);
|
1018
|
-
GetColumnBinding(*comparison.right, filter_info->right_binding);
|
1019
|
-
if (!left_bindings.empty() && !right_bindings.empty()) {
|
1020
|
-
// both the left and the right side have bindings
|
1021
|
-
// first create the relation sets, if they do not exist
|
1022
|
-
filter_info->left_set = &set_manager.GetJoinRelation(left_bindings);
|
1023
|
-
filter_info->right_set = &set_manager.GetJoinRelation(right_bindings);
|
1024
|
-
// we can only create a meaningful edge if the sets are not exactly the same
|
1025
|
-
if (filter_info->left_set != filter_info->right_set) {
|
1026
|
-
// check if the sets are disjoint
|
1027
|
-
if (Disjoint(left_bindings, right_bindings)) {
|
1028
|
-
// they are disjoint, we only need to create one set of edges in the join graph
|
1029
|
-
query_graph.CreateEdge(*filter_info->left_set, *filter_info->right_set, filter_info);
|
1030
|
-
query_graph.CreateEdge(*filter_info->right_set, *filter_info->left_set, filter_info);
|
1031
|
-
} else {
|
1032
|
-
continue;
|
1033
|
-
}
|
1034
|
-
continue;
|
1035
|
-
}
|
1036
|
-
}
|
1037
|
-
}
|
1038
|
-
}
|
1039
|
-
// now use dynamic programming to figure out the optimal join order
|
1040
|
-
// First we initialize each of the single-node plans with themselves and with their cardinalities these are the leaf
|
1041
|
-
// nodes of the join tree NOTE: we can just use pointers to JoinRelationSet* here because the GetJoinRelation
|
1042
|
-
// function ensures that a unique combination of relations will have a unique JoinRelationSet object.
|
1043
|
-
vector<NodeOp> nodes_ops;
|
1044
|
-
for (idx_t i = 0; i < relations.size(); i++) {
|
1045
|
-
auto &rel = *relations[i];
|
1046
|
-
auto &node = set_manager.GetJoinRelation(i);
|
1047
|
-
nodes_ops.emplace_back(make_uniq<JoinNode>(node, 0), rel.op);
|
74
|
+
// Propagate up a stats object from the top of the new_logical_plan if stats exist.
|
75
|
+
if (stats) {
|
76
|
+
auto cardinality = new_logical_plan->EstimateCardinality(context);
|
77
|
+
auto bindings = new_logical_plan->GetColumnBindings();
|
78
|
+
auto new_stats = RelationStatisticsHelper::CombineStatsOfReorderableOperator(bindings, relation_stats);
|
79
|
+
new_stats.cardinality = MaxValue(cardinality, new_stats.cardinality);
|
80
|
+
RelationStatisticsHelper::CopyRelationStats(*stats, new_stats);
|
1048
81
|
}
|
1049
82
|
|
1050
|
-
|
1051
|
-
|
1052
|
-
for (auto &node_op : nodes_ops) {
|
1053
|
-
D_ASSERT(node_op.node);
|
1054
|
-
plans[&node_op.node->set] = std::move(node_op.node);
|
1055
|
-
}
|
1056
|
-
// now we perform the actual dynamic programming to compute the final result
|
1057
|
-
SolveJoinOrder();
|
1058
|
-
// now the optimal join path should have been found
|
1059
|
-
// get it from the node
|
1060
|
-
unordered_set<idx_t> bindings;
|
1061
|
-
for (idx_t i = 0; i < relations.size(); i++) {
|
1062
|
-
bindings.insert(i);
|
1063
|
-
}
|
1064
|
-
auto &total_relation = set_manager.GetJoinRelation(bindings);
|
1065
|
-
auto final_plan = plans.find(&total_relation);
|
1066
|
-
if (final_plan == plans.end()) {
|
1067
|
-
// could not find the final plan
|
1068
|
-
// this should only happen in case the sets are actually disjunct
|
1069
|
-
// in this case we need to generate cross product to connect the disjoint sets
|
1070
|
-
if (context.config.force_no_cross_product) {
|
1071
|
-
throw InvalidInputException(
|
1072
|
-
"Query requires a cross-product, but 'force_no_cross_product' PRAGMA is enabled");
|
1073
|
-
}
|
1074
|
-
GenerateCrossProducts();
|
1075
|
-
//! solve the join order again
|
1076
|
-
SolveJoinOrder();
|
1077
|
-
// now we can obtain the final plan!
|
1078
|
-
final_plan = plans.find(&total_relation);
|
1079
|
-
D_ASSERT(final_plan != plans.end());
|
1080
|
-
}
|
1081
|
-
// now perform the actual reordering
|
1082
|
-
return RewritePlan(std::move(plan), *final_plan->second);
|
83
|
+
return new_logical_plan;
|
1083
84
|
}
|
1084
85
|
|
1085
86
|
} // namespace duckdb
|