duckdb 1.1.4-dev9.0 → 1.2.1-dev4.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/LICENSE +1 -1
- package/binding.gyp +1 -0
- package/package.json +2 -2
- package/src/connection.cpp +42 -15
- package/src/duckdb/extension/core_functions/function_list.cpp +1 -0
- package/src/duckdb/extension/core_functions/include/core_functions/scalar/map_functions.hpp +9 -0
- package/src/duckdb/extension/core_functions/scalar/date/current.cpp +1 -0
- package/src/duckdb/extension/core_functions/scalar/generic/can_implicitly_cast.cpp +2 -2
- package/src/duckdb/extension/core_functions/scalar/generic/typeof.cpp +1 -1
- package/src/duckdb/extension/core_functions/scalar/list/flatten.cpp +91 -61
- package/src/duckdb/extension/core_functions/scalar/map/map_extract.cpp +89 -8
- package/src/duckdb/extension/icu/icu-current.cpp +63 -0
- package/src/duckdb/extension/icu/icu-makedate.cpp +43 -39
- package/src/duckdb/extension/icu/icu-timezone.cpp +63 -63
- package/src/duckdb/extension/icu/icu_extension.cpp +2 -0
- package/src/duckdb/extension/icu/include/icu-casts.hpp +39 -0
- package/src/duckdb/extension/icu/include/icu-current.hpp +17 -0
- package/src/duckdb/extension/icu/third_party/icu/stubdata/stubdata.cpp +1 -1
- package/src/duckdb/extension/json/json_functions/json_structure.cpp +3 -1
- package/src/duckdb/extension/parquet/column_writer.cpp +26 -18
- package/src/duckdb/extension/parquet/include/parquet_reader.hpp +0 -6
- package/src/duckdb/extension/parquet/include/parquet_writer.hpp +15 -1
- package/src/duckdb/extension/parquet/include/resizable_buffer.hpp +1 -0
- package/src/duckdb/extension/parquet/parquet_extension.cpp +67 -15
- package/src/duckdb/extension/parquet/parquet_reader.cpp +5 -3
- package/src/duckdb/extension/parquet/parquet_writer.cpp +5 -6
- package/src/duckdb/src/catalog/catalog.cpp +21 -8
- package/src/duckdb/src/catalog/catalog_search_path.cpp +17 -1
- package/src/duckdb/src/catalog/catalog_set.cpp +1 -1
- package/src/duckdb/src/catalog/default/default_functions.cpp +0 -3
- package/src/duckdb/src/catalog/dependency_list.cpp +7 -0
- package/src/duckdb/src/common/adbc/adbc.cpp +1 -56
- package/src/duckdb/src/common/arrow/arrow_converter.cpp +3 -2
- package/src/duckdb/src/common/arrow/arrow_type_extension.cpp +58 -28
- package/src/duckdb/src/common/arrow/schema_metadata.cpp +1 -1
- package/src/duckdb/src/common/compressed_file_system.cpp +6 -2
- package/src/duckdb/src/common/enum_util.cpp +26 -22
- package/src/duckdb/src/common/error_data.cpp +3 -2
- package/src/duckdb/src/common/gzip_file_system.cpp +8 -8
- package/src/duckdb/src/common/local_file_system.cpp +2 -2
- package/src/duckdb/src/common/multi_file_reader.cpp +1 -1
- package/src/duckdb/src/common/random_engine.cpp +4 -1
- package/src/duckdb/src/common/serializer/memory_stream.cpp +23 -19
- package/src/duckdb/src/common/serializer/serializer.cpp +1 -1
- package/src/duckdb/src/common/types/bit.cpp +1 -1
- package/src/duckdb/src/common/types/column/column_data_allocator.cpp +0 -5
- package/src/duckdb/src/common/types/column/column_data_collection.cpp +4 -1
- package/src/duckdb/src/common/types/data_chunk.cpp +2 -1
- package/src/duckdb/src/common/types/row/tuple_data_segment.cpp +0 -4
- package/src/duckdb/src/common/types.cpp +1 -1
- package/src/duckdb/src/execution/index/art/art.cpp +52 -42
- package/src/duckdb/src/execution/index/art/leaf.cpp +4 -9
- package/src/duckdb/src/execution/index/art/node.cpp +13 -13
- package/src/duckdb/src/execution/index/art/prefix.cpp +21 -16
- package/src/duckdb/src/execution/index/bound_index.cpp +6 -8
- package/src/duckdb/src/execution/index/fixed_size_allocator.cpp +39 -34
- package/src/duckdb/src/execution/index/fixed_size_buffer.cpp +2 -1
- package/src/duckdb/src/execution/index/unbound_index.cpp +10 -0
- package/src/duckdb/src/execution/operator/aggregate/physical_streaming_window.cpp +62 -44
- package/src/duckdb/src/execution/operator/csv_scanner/scanner/column_count_scanner.cpp +26 -0
- package/src/duckdb/src/execution/operator/csv_scanner/scanner/string_value_scanner.cpp +69 -40
- package/src/duckdb/src/execution/operator/csv_scanner/sniffer/dialect_detection.cpp +3 -7
- package/src/duckdb/src/execution/operator/csv_scanner/sniffer/header_detection.cpp +11 -5
- package/src/duckdb/src/execution/operator/csv_scanner/sniffer/type_detection.cpp +4 -0
- package/src/duckdb/src/execution/operator/csv_scanner/state_machine/csv_state_machine_cache.cpp +8 -8
- package/src/duckdb/src/execution/operator/csv_scanner/util/csv_error.cpp +36 -12
- package/src/duckdb/src/execution/operator/csv_scanner/util/csv_reader_options.cpp +12 -9
- package/src/duckdb/src/execution/operator/join/physical_hash_join.cpp +0 -1
- package/src/duckdb/src/execution/operator/persistent/physical_copy_database.cpp +29 -1
- package/src/duckdb/src/execution/operator/persistent/physical_delete.cpp +58 -10
- package/src/duckdb/src/execution/operator/persistent/physical_insert.cpp +58 -35
- package/src/duckdb/src/execution/operator/schema/physical_create_art_index.cpp +2 -1
- package/src/duckdb/src/execution/radix_partitioned_hashtable.cpp +9 -4
- package/src/duckdb/src/execution/sample/reservoir_sample.cpp +7 -6
- package/src/duckdb/src/function/compression_config.cpp +4 -0
- package/src/duckdb/src/function/function_binder.cpp +1 -1
- package/src/duckdb/src/function/scalar/system/write_log.cpp +2 -2
- package/src/duckdb/src/function/table/arrow/arrow_duck_schema.cpp +15 -2
- package/src/duckdb/src/function/table/arrow_conversion.cpp +10 -10
- package/src/duckdb/src/function/table/copy_csv.cpp +8 -5
- package/src/duckdb/src/function/table/read_csv.cpp +21 -4
- package/src/duckdb/src/function/table/sniff_csv.cpp +7 -0
- package/src/duckdb/src/function/table/system/duckdb_extensions.cpp +4 -0
- package/src/duckdb/src/function/table/system/duckdb_secret_types.cpp +71 -0
- package/src/duckdb/src/function/table/system_functions.cpp +1 -0
- package/src/duckdb/src/function/table/table_scan.cpp +120 -36
- package/src/duckdb/src/function/table/version/pragma_version.cpp +4 -4
- package/src/duckdb/src/function/window/window_aggregate_function.cpp +6 -1
- package/src/duckdb/src/function/window/window_boundaries_state.cpp +135 -11
- package/src/duckdb/src/function/window/window_segment_tree.cpp +50 -22
- package/src/duckdb/src/function/window/window_token_tree.cpp +4 -3
- package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +4 -0
- package/src/duckdb/src/include/duckdb/catalog/catalog_search_path.hpp +2 -0
- package/src/duckdb/src/include/duckdb/catalog/dependency_list.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/arrow/arrow_type_extension.hpp +4 -2
- package/src/duckdb/src/include/duckdb/common/enum_util.hpp +8 -8
- package/src/duckdb/src/include/duckdb/common/multi_file_reader.hpp +0 -2
- package/src/duckdb/src/include/duckdb/common/serializer/deserializer.hpp +8 -3
- package/src/duckdb/src/include/duckdb/common/serializer/memory_stream.hpp +6 -1
- package/src/duckdb/src/include/duckdb/common/serializer/serialization_data.hpp +25 -0
- package/src/duckdb/src/include/duckdb/common/serializer/serializer.hpp +9 -3
- package/src/duckdb/src/include/duckdb/common/types/selection_vector.hpp +1 -1
- package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +11 -14
- package/src/duckdb/src/include/duckdb/execution/index/art/prefix.hpp +5 -4
- package/src/duckdb/src/include/duckdb/execution/index/bound_index.hpp +21 -10
- package/src/duckdb/src/include/duckdb/execution/index/fixed_size_allocator.hpp +6 -5
- package/src/duckdb/src/include/duckdb/execution/index/fixed_size_buffer.hpp +37 -32
- package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/base_scanner.hpp +36 -1
- package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/column_count_scanner.hpp +3 -0
- package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/sniffer/csv_sniffer.hpp +2 -0
- package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/state_machine_options.hpp +5 -5
- package/src/duckdb/src/include/duckdb/execution/operator/csv_scanner/string_value_scanner.hpp +5 -30
- package/src/duckdb/src/include/duckdb/execution/reservoir_sample.hpp +7 -1
- package/src/duckdb/src/include/duckdb/function/scalar_function.hpp +3 -3
- package/src/duckdb/src/include/duckdb/function/table/arrow/arrow_duck_schema.hpp +1 -0
- package/src/duckdb/src/include/duckdb/function/table/system_functions.hpp +4 -0
- package/src/duckdb/src/include/duckdb/function/window/window_boundaries_state.hpp +2 -2
- package/src/duckdb/src/include/duckdb/logging/logger.hpp +40 -119
- package/src/duckdb/src/include/duckdb/logging/logging.hpp +0 -2
- package/src/duckdb/src/include/duckdb/main/config.hpp +5 -0
- package/src/duckdb/src/include/duckdb/main/connection.hpp +0 -8
- package/src/duckdb/src/include/duckdb/main/connection_manager.hpp +2 -1
- package/src/duckdb/src/include/duckdb/main/extension.hpp +1 -0
- package/src/duckdb/src/include/duckdb/main/extension_entries.hpp +11 -7
- package/src/duckdb/src/include/duckdb/main/extension_helper.hpp +1 -0
- package/src/duckdb/src/include/duckdb/main/secret/secret.hpp +2 -0
- package/src/duckdb/src/include/duckdb/main/secret/secret_manager.hpp +3 -0
- package/src/duckdb/src/include/duckdb/main/settings.hpp +10 -0
- package/src/duckdb/src/include/duckdb/parser/constraint.hpp +9 -0
- package/src/duckdb/src/include/duckdb/parser/expression/window_expression.hpp +36 -9
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_view_info.hpp +2 -1
- package/src/duckdb/src/include/duckdb/parser/query_node/set_operation_node.hpp +8 -2
- package/src/duckdb/src/include/duckdb/planner/binder.hpp +4 -0
- package/src/duckdb/src/include/duckdb/planner/expression/bound_parameter_data.hpp +9 -1
- package/src/duckdb/src/include/duckdb/planner/filter/constant_filter.hpp +1 -0
- package/src/duckdb/src/include/duckdb/planner/filter/in_filter.hpp +0 -2
- package/src/duckdb/src/include/duckdb/planner/filter/optional_filter.hpp +4 -4
- package/src/duckdb/src/include/duckdb/planner/table_filter.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/data_table.hpp +14 -10
- package/src/duckdb/src/include/duckdb/storage/index_storage_info.hpp +4 -0
- package/src/duckdb/src/include/duckdb/storage/single_file_block_manager.hpp +6 -1
- package/src/duckdb/src/include/duckdb/storage/storage_info.hpp +7 -2
- package/src/duckdb/src/include/duckdb/storage/storage_manager.hpp +9 -0
- package/src/duckdb/src/include/duckdb/storage/storage_options.hpp +2 -0
- package/src/duckdb/src/include/duckdb/storage/string_uncompressed.hpp +4 -3
- package/src/duckdb/src/include/duckdb/storage/table/column_data.hpp +2 -0
- package/src/duckdb/src/include/duckdb/storage/table/table_index_list.hpp +6 -4
- package/src/duckdb/src/include/duckdb/storage/table/table_statistics.hpp +1 -1
- package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +2 -0
- package/src/duckdb/src/include/duckdb/transaction/local_storage.hpp +2 -0
- package/src/duckdb/src/include/duckdb/transaction/meta_transaction.hpp +1 -1
- package/src/duckdb/src/logging/logger.cpp +8 -66
- package/src/duckdb/src/main/attached_database.cpp +3 -1
- package/src/duckdb/src/main/client_context.cpp +4 -2
- package/src/duckdb/src/main/config.cpp +20 -2
- package/src/duckdb/src/main/connection.cpp +2 -29
- package/src/duckdb/src/main/connection_manager.cpp +5 -3
- package/src/duckdb/src/main/database.cpp +2 -2
- package/src/duckdb/src/main/extension/extension_helper.cpp +4 -5
- package/src/duckdb/src/main/extension/extension_install.cpp +23 -10
- package/src/duckdb/src/main/extension/extension_load.cpp +6 -7
- package/src/duckdb/src/main/extension.cpp +27 -9
- package/src/duckdb/src/main/secret/secret_manager.cpp +11 -0
- package/src/duckdb/src/main/settings/custom_settings.cpp +44 -0
- package/src/duckdb/src/optimizer/column_lifetime_analyzer.cpp +6 -0
- package/src/duckdb/src/optimizer/filter_combiner.cpp +13 -3
- package/src/duckdb/src/optimizer/filter_pushdown.cpp +33 -6
- package/src/duckdb/src/optimizer/late_materialization.cpp +14 -3
- package/src/duckdb/src/optimizer/remove_unused_columns.cpp +0 -3
- package/src/duckdb/src/parser/parsed_data/attach_info.cpp +5 -1
- package/src/duckdb/src/parser/parsed_data/create_view_info.cpp +6 -3
- package/src/duckdb/src/parser/query_node/set_operation_node.cpp +49 -0
- package/src/duckdb/src/parser/transform/expression/transform_columnref.cpp +1 -0
- package/src/duckdb/src/parser/transform/expression/transform_function.cpp +50 -12
- package/src/duckdb/src/planner/binder/expression/bind_columnref_expression.cpp +7 -5
- package/src/duckdb/src/planner/binder/expression/bind_comparison_expression.cpp +1 -0
- package/src/duckdb/src/planner/binder/expression/bind_operator_expression.cpp +2 -2
- package/src/duckdb/src/planner/binder/expression/bind_star_expression.cpp +12 -2
- package/src/duckdb/src/planner/binder/statement/bind_copy_database.cpp +0 -1
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +55 -39
- package/src/duckdb/src/planner/binder/statement/bind_execute.cpp +2 -1
- package/src/duckdb/src/planner/binder/tableref/bind_basetableref.cpp +15 -7
- package/src/duckdb/src/planner/binder/tableref/bind_showref.cpp +13 -8
- package/src/duckdb/src/planner/binder/tableref/bind_table_function.cpp +8 -3
- package/src/duckdb/src/planner/expression/bound_function_expression.cpp +17 -1
- package/src/duckdb/src/planner/expression_binder/index_binder.cpp +1 -0
- package/src/duckdb/src/planner/filter/conjunction_filter.cpp +1 -0
- package/src/duckdb/src/planner/filter/constant_filter.cpp +21 -0
- package/src/duckdb/src/planner/filter/in_filter.cpp +4 -7
- package/src/duckdb/src/planner/logical_operator.cpp +5 -3
- package/src/duckdb/src/planner/planner.cpp +1 -1
- package/src/duckdb/src/planner/subquery/flatten_dependent_join.cpp +2 -0
- package/src/duckdb/src/storage/checkpoint/table_data_writer.cpp +3 -4
- package/src/duckdb/src/storage/checkpoint_manager.cpp +3 -5
- package/src/duckdb/src/storage/compression/dictionary/decompression.cpp +4 -4
- package/src/duckdb/src/storage/compression/fsst.cpp +2 -2
- package/src/duckdb/src/storage/compression/roaring/common.cpp +10 -1
- package/src/duckdb/src/storage/compression/string_uncompressed.cpp +11 -6
- package/src/duckdb/src/storage/compression/validity_uncompressed.cpp +4 -0
- package/src/duckdb/src/storage/compression/zstd.cpp +6 -0
- package/src/duckdb/src/storage/data_table.cpp +104 -109
- package/src/duckdb/src/storage/local_storage.cpp +8 -6
- package/src/duckdb/src/storage/magic_bytes.cpp +1 -1
- package/src/duckdb/src/storage/serialization/serialize_dependency.cpp +3 -3
- package/src/duckdb/src/storage/serialization/serialize_nodes.cpp +3 -3
- package/src/duckdb/src/storage/serialization/serialize_query_node.cpp +7 -5
- package/src/duckdb/src/storage/single_file_block_manager.cpp +95 -28
- package/src/duckdb/src/storage/storage_info.cpp +38 -0
- package/src/duckdb/src/storage/storage_manager.cpp +11 -0
- package/src/duckdb/src/storage/table/column_data.cpp +4 -0
- package/src/duckdb/src/storage/table/column_data_checkpointer.cpp +3 -3
- package/src/duckdb/src/storage/table/row_group_collection.cpp +67 -68
- package/src/duckdb/src/storage/table/table_statistics.cpp +4 -4
- package/src/duckdb/src/storage/table_index_list.cpp +41 -15
- package/src/duckdb/src/storage/wal_replay.cpp +3 -1
- package/src/duckdb/src/storage/write_ahead_log.cpp +11 -4
- package/src/duckdb/src/transaction/meta_transaction.cpp +1 -1
- package/src/duckdb/src/verification/deserialized_statement_verifier.cpp +2 -1
- package/src/duckdb/third_party/httplib/httplib.hpp +0 -1
- package/src/duckdb/third_party/re2/util/logging.h +10 -10
- package/src/duckdb/ub_src_function_table_system.cpp +2 -0
@@ -149,11 +149,15 @@ unique_ptr<GlobalTableFunctionState> DuckDBExtensionsInit(ClientContext &context
|
|
149
149
|
auto entry = installed_extensions.find(ext_name);
|
150
150
|
if (entry == installed_extensions.end() || !entry->second.installed) {
|
151
151
|
ExtensionInformation &info = installed_extensions[ext_name];
|
152
|
+
|
152
153
|
info.name = ext_name;
|
153
154
|
info.loaded = true;
|
154
155
|
info.extension_version = ext_install_info->version;
|
155
156
|
info.installed = ext_install_info->mode == ExtensionInstallMode::STATICALLY_LINKED;
|
156
157
|
info.install_mode = ext_install_info->mode;
|
158
|
+
if (ext_data.install_info->mode == ExtensionInstallMode::STATICALLY_LINKED && info.file_path.empty()) {
|
159
|
+
info.file_path = "(BUILT-IN)";
|
160
|
+
}
|
157
161
|
} else {
|
158
162
|
entry->second.loaded = true;
|
159
163
|
entry->second.extension_version = ext_install_info->version;
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#include "duckdb/function/table/system_functions.hpp"
|
2
|
+
#include "duckdb/main/config.hpp"
|
3
|
+
#include "duckdb/main/client_context.hpp"
|
4
|
+
#include "duckdb/common/enum_util.hpp"
|
5
|
+
#include "duckdb/main/secret/secret_manager.hpp"
|
6
|
+
#include "duckdb/main/secret/secret.hpp"
|
7
|
+
|
8
|
+
namespace duckdb {
|
9
|
+
|
10
|
+
struct DuckDBSecretTypesData : public GlobalTableFunctionState {
|
11
|
+
DuckDBSecretTypesData() : offset(0) {
|
12
|
+
}
|
13
|
+
|
14
|
+
vector<SecretType> types;
|
15
|
+
idx_t offset;
|
16
|
+
};
|
17
|
+
|
18
|
+
static unique_ptr<FunctionData> DuckDBSecretTypesBind(ClientContext &context, TableFunctionBindInput &input,
|
19
|
+
vector<LogicalType> &return_types, vector<string> &names) {
|
20
|
+
names.emplace_back("type");
|
21
|
+
return_types.emplace_back(LogicalType::VARCHAR);
|
22
|
+
|
23
|
+
names.emplace_back("default_provider");
|
24
|
+
return_types.emplace_back(LogicalType::VARCHAR);
|
25
|
+
|
26
|
+
names.emplace_back("extension");
|
27
|
+
return_types.emplace_back(LogicalType::VARCHAR);
|
28
|
+
|
29
|
+
return nullptr;
|
30
|
+
}
|
31
|
+
|
32
|
+
unique_ptr<GlobalTableFunctionState> DuckDBSecretTypesInit(ClientContext &context, TableFunctionInitInput &input) {
|
33
|
+
auto result = make_uniq<DuckDBSecretTypesData>();
|
34
|
+
|
35
|
+
auto &secret_manager = SecretManager::Get(context);
|
36
|
+
result->types = secret_manager.AllSecretTypes();
|
37
|
+
|
38
|
+
return std::move(result);
|
39
|
+
}
|
40
|
+
|
41
|
+
void DuckDBSecretTypesFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) {
|
42
|
+
auto &data = data_p.global_state->Cast<DuckDBSecretTypesData>();
|
43
|
+
if (data.offset >= data.types.size()) {
|
44
|
+
// finished returning values
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
// start returning values
|
48
|
+
// either fill up the chunk or return all the remaining columns
|
49
|
+
idx_t count = 0;
|
50
|
+
while (data.offset < data.types.size() && count < STANDARD_VECTOR_SIZE) {
|
51
|
+
auto &entry = data.types[data.offset++];
|
52
|
+
|
53
|
+
// return values:
|
54
|
+
// type, LogicalType::VARCHAR
|
55
|
+
output.SetValue(0, count, Value(entry.name));
|
56
|
+
// default_provider, LogicalType::VARCHAR
|
57
|
+
output.SetValue(1, count, Value(entry.default_provider));
|
58
|
+
// extension, LogicalType::VARCHAR
|
59
|
+
output.SetValue(2, count, Value(entry.extension));
|
60
|
+
|
61
|
+
count++;
|
62
|
+
}
|
63
|
+
output.SetCardinality(count);
|
64
|
+
}
|
65
|
+
|
66
|
+
void DuckDBSecretTypesFun::RegisterFunction(BuiltinFunctions &set) {
|
67
|
+
set.AddFunction(TableFunction("duckdb_secret_types", {}, DuckDBSecretTypesFunction, DuckDBSecretTypesBind,
|
68
|
+
DuckDBSecretTypesInit));
|
69
|
+
}
|
70
|
+
|
71
|
+
} // namespace duckdb
|
@@ -33,6 +33,7 @@ void BuiltinFunctions::RegisterSQLiteFunctions() {
|
|
33
33
|
DuckDBOptimizersFun::RegisterFunction(*this);
|
34
34
|
DuckDBSecretsFun::RegisterFunction(*this);
|
35
35
|
DuckDBWhichSecretFun::RegisterFunction(*this);
|
36
|
+
DuckDBSecretTypesFun::RegisterFunction(*this);
|
36
37
|
DuckDBSequencesFun::RegisterFunction(*this);
|
37
38
|
DuckDBSettingsFun::RegisterFunction(*this);
|
38
39
|
DuckDBTablesFun::RegisterFunction(*this);
|
@@ -24,6 +24,7 @@
|
|
24
24
|
#include "duckdb/planner/expression/bound_constant_expression.hpp"
|
25
25
|
#include "duckdb/planner/expression/bound_comparison_expression.hpp"
|
26
26
|
#include "duckdb/planner/filter/conjunction_filter.hpp"
|
27
|
+
#include "duckdb/common/types/value_map.hpp"
|
27
28
|
|
28
29
|
namespace duckdb {
|
29
30
|
|
@@ -41,6 +42,8 @@ struct IndexScanLocalState : public LocalTableFunctionState {
|
|
41
42
|
//! The DataChunk containing all read columns.
|
42
43
|
//! This includes filter columns, which are immediately removed.
|
43
44
|
DataChunk all_columns;
|
45
|
+
//! Fetch state
|
46
|
+
ColumnFetchState fetch_state;
|
44
47
|
};
|
45
48
|
|
46
49
|
static StorageIndex TransformStorageIndex(const ColumnIndex &column_id) {
|
@@ -115,7 +118,6 @@ public:
|
|
115
118
|
//! Synchronize changes to the global index scan state.
|
116
119
|
mutex index_scan_lock;
|
117
120
|
|
118
|
-
ColumnFetchState fetch_state;
|
119
121
|
TableScanState table_scan_state;
|
120
122
|
|
121
123
|
public:
|
@@ -159,10 +161,10 @@ public:
|
|
159
161
|
|
160
162
|
if (CanRemoveFilterColumns()) {
|
161
163
|
l_state.all_columns.Reset();
|
162
|
-
storage.Fetch(tx, l_state.all_columns, column_ids, local_vector, scan_count, fetch_state);
|
164
|
+
storage.Fetch(tx, l_state.all_columns, column_ids, local_vector, scan_count, l_state.fetch_state);
|
163
165
|
output.ReferenceColumns(l_state.all_columns, projection_ids);
|
164
166
|
} else {
|
165
|
-
storage.Fetch(tx, output, column_ids, local_vector, scan_count, fetch_state);
|
167
|
+
storage.Fetch(tx, output, column_ids, local_vector, scan_count, l_state.fetch_state);
|
166
168
|
}
|
167
169
|
}
|
168
170
|
|
@@ -361,56 +363,137 @@ unique_ptr<GlobalTableFunctionState> DuckIndexScanInitGlobal(ClientContext &cont
|
|
361
363
|
return std::move(g_state);
|
362
364
|
}
|
363
365
|
|
364
|
-
void
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
366
|
+
void ExtractExpressionsFromValues(value_set_t &unique_values, BoundColumnRefExpression &bound_ref,
|
367
|
+
vector<unique_ptr<Expression>> &expressions) {
|
368
|
+
for (const auto &value : unique_values) {
|
369
|
+
auto bound_constant = make_uniq<BoundConstantExpression>(value);
|
370
|
+
auto filter_expr = make_uniq<BoundComparisonExpression>(ExpressionType::COMPARE_EQUAL, bound_ref.Copy(),
|
371
|
+
std::move(bound_constant));
|
372
|
+
expressions.push_back(std::move(filter_expr));
|
370
373
|
}
|
374
|
+
}
|
371
375
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
+
void ExtractIn(InFilter &filter, BoundColumnRefExpression &bound_ref, vector<unique_ptr<Expression>> &expressions) {
|
377
|
+
// Eliminate any duplicates.
|
378
|
+
value_set_t unique_values;
|
379
|
+
for (const auto &value : filter.values) {
|
380
|
+
if (unique_values.find(value) == unique_values.end()) {
|
381
|
+
unique_values.insert(value);
|
382
|
+
}
|
376
383
|
}
|
377
|
-
|
384
|
+
ExtractExpressionsFromValues(unique_values, bound_ref, expressions);
|
385
|
+
}
|
386
|
+
|
387
|
+
void ExtractConjunctionAnd(ConjunctionAndFilter &filter, BoundColumnRefExpression &bound_ref,
|
388
|
+
vector<unique_ptr<Expression>> &expressions) {
|
389
|
+
if (filter.child_filters.empty()) {
|
378
390
|
return;
|
379
391
|
}
|
380
392
|
|
381
|
-
|
382
|
-
|
383
|
-
|
393
|
+
// Extract the CONSTANT_COMPARISON and IN_FILTER children.
|
394
|
+
vector<reference<ConstantFilter>> comparisons;
|
395
|
+
vector<reference<InFilter>> in_filters;
|
396
|
+
|
397
|
+
for (idx_t i = 0; i < filter.child_filters.size(); i++) {
|
398
|
+
if (filter.child_filters[i]->filter_type == TableFilterType::CONSTANT_COMPARISON) {
|
399
|
+
auto &comparison = filter.child_filters[i]->Cast<ConstantFilter>();
|
400
|
+
comparisons.push_back(comparison);
|
401
|
+
continue;
|
402
|
+
}
|
403
|
+
|
404
|
+
if (filter.child_filters[i]->filter_type == TableFilterType::OPTIONAL_FILTER) {
|
405
|
+
auto &optional_filter = filter.child_filters[i]->Cast<OptionalFilter>();
|
406
|
+
if (!optional_filter.child_filter) {
|
407
|
+
return;
|
408
|
+
}
|
409
|
+
if (optional_filter.child_filter->filter_type != TableFilterType::IN_FILTER) {
|
410
|
+
// No support for other optional filter types yet.
|
411
|
+
return;
|
412
|
+
}
|
413
|
+
auto &in_filter = optional_filter.child_filter->Cast<InFilter>();
|
414
|
+
in_filters.push_back(in_filter);
|
415
|
+
continue;
|
416
|
+
}
|
417
|
+
|
418
|
+
// No support for other filter types than CONSTANT_COMPARISON and IN_FILTER in CONJUNCTION_AND yet.
|
384
419
|
return;
|
385
420
|
}
|
386
421
|
|
387
|
-
|
388
|
-
if (
|
422
|
+
// No support for other CONJUNCTION_AND cases yet.
|
423
|
+
if (in_filters.empty()) {
|
389
424
|
return;
|
390
425
|
}
|
391
426
|
|
392
|
-
//
|
393
|
-
|
394
|
-
|
395
|
-
auto
|
396
|
-
|
397
|
-
|
427
|
+
// Get the combined unique values of the IN filters.
|
428
|
+
value_set_t unique_values;
|
429
|
+
for (idx_t filter_idx = 0; filter_idx < in_filters.size(); filter_idx++) {
|
430
|
+
auto &in_filter = in_filters[filter_idx].get();
|
431
|
+
for (idx_t value_idx = 0; value_idx < in_filter.values.size(); value_idx++) {
|
432
|
+
auto &value = in_filter.values[value_idx];
|
433
|
+
if (unique_values.find(value) != unique_values.end()) {
|
434
|
+
continue;
|
435
|
+
}
|
436
|
+
unique_values.insert(value);
|
437
|
+
}
|
438
|
+
}
|
439
|
+
|
440
|
+
// Extract all qualifying values.
|
441
|
+
for (auto value_it = unique_values.begin(); value_it != unique_values.end();) {
|
442
|
+
bool qualifies = true;
|
443
|
+
for (idx_t comp_idx = 0; comp_idx < comparisons.size(); comp_idx++) {
|
444
|
+
if (!comparisons[comp_idx].get().Compare(*value_it)) {
|
445
|
+
qualifies = false;
|
446
|
+
value_it = unique_values.erase(value_it);
|
447
|
+
break;
|
448
|
+
}
|
449
|
+
}
|
450
|
+
if (qualifies) {
|
451
|
+
value_it++;
|
452
|
+
}
|
453
|
+
}
|
454
|
+
|
455
|
+
ExtractExpressionsFromValues(unique_values, bound_ref, expressions);
|
456
|
+
}
|
457
|
+
|
458
|
+
void ExtractFilter(TableFilter &filter, BoundColumnRefExpression &bound_ref,
|
459
|
+
vector<unique_ptr<Expression>> &expressions) {
|
460
|
+
switch (filter.filter_type) {
|
461
|
+
case TableFilterType::OPTIONAL_FILTER: {
|
462
|
+
auto &optional_filter = filter.Cast<OptionalFilter>();
|
463
|
+
if (!optional_filter.child_filter) {
|
464
|
+
return;
|
465
|
+
}
|
466
|
+
return ExtractFilter(*optional_filter.child_filter, bound_ref, expressions);
|
467
|
+
}
|
468
|
+
case TableFilterType::IN_FILTER: {
|
469
|
+
auto &in_filter = filter.Cast<InFilter>();
|
470
|
+
ExtractIn(in_filter, bound_ref, expressions);
|
471
|
+
return;
|
472
|
+
}
|
473
|
+
case TableFilterType::CONJUNCTION_AND: {
|
474
|
+
auto &conjunction_and = filter.Cast<ConjunctionAndFilter>();
|
475
|
+
ExtractConjunctionAnd(conjunction_and, bound_ref, expressions);
|
476
|
+
return;
|
477
|
+
}
|
478
|
+
default:
|
479
|
+
return;
|
398
480
|
}
|
399
481
|
}
|
400
482
|
|
401
|
-
|
402
|
-
|
483
|
+
vector<unique_ptr<Expression>> ExtractFilterExpressions(const ColumnDefinition &col, unique_ptr<TableFilter> &filter,
|
484
|
+
idx_t storage_idx) {
|
403
485
|
ColumnBinding binding(0, storage_idx);
|
404
486
|
auto bound_ref = make_uniq<BoundColumnRefExpression>(col.Name(), col.Type(), binding);
|
405
487
|
|
406
|
-
|
407
|
-
|
488
|
+
vector<unique_ptr<Expression>> expressions;
|
489
|
+
ExtractFilter(*filter, *bound_ref, expressions);
|
408
490
|
|
409
|
-
|
491
|
+
// Attempt matching the top-level filter to the index expression.
|
492
|
+
if (expressions.empty()) {
|
410
493
|
auto filter_expr = filter->ToExpression(*bound_ref);
|
411
|
-
|
494
|
+
expressions.push_back(std::move(filter_expr));
|
412
495
|
}
|
413
|
-
return
|
496
|
+
return expressions;
|
414
497
|
}
|
415
498
|
|
416
499
|
bool TryScanIndex(ART &art, const ColumnList &column_list, TableFunctionInitInput &input, TableFilterSet &filter_set,
|
@@ -453,8 +536,8 @@ bool TryScanIndex(ART &art, const ColumnList &column_list, TableFunctionInitInpu
|
|
453
536
|
return false;
|
454
537
|
}
|
455
538
|
|
456
|
-
auto
|
457
|
-
for (const auto &filter_expr :
|
539
|
+
auto expressions = ExtractFilterExpressions(col, filter->second, storage_index.GetIndex());
|
540
|
+
for (const auto &filter_expr : expressions) {
|
458
541
|
auto scan_state = art.TryInitializeScan(*index_expr, *filter_expr);
|
459
542
|
if (!scan_state) {
|
460
543
|
return false;
|
@@ -493,7 +576,8 @@ unique_ptr<GlobalTableFunctionState> TableScanInitGlobal(ClientContext &context,
|
|
493
576
|
}
|
494
577
|
|
495
578
|
// The checkpoint lock ensures that we do not checkpoint while scanning this table.
|
496
|
-
auto
|
579
|
+
auto &transaction = DuckTransaction::Get(context, storage.db);
|
580
|
+
auto checkpoint_lock = transaction.SharedLockTable(*storage.GetDataTableInfo());
|
497
581
|
auto &info = storage.GetDataTableInfo();
|
498
582
|
auto &indexes = info->GetIndexes();
|
499
583
|
if (indexes.Empty()) {
|
@@ -588,7 +672,7 @@ InsertionOrderPreservingMap<string> TableScanToString(TableFunctionToStringInput
|
|
588
672
|
InsertionOrderPreservingMap<string> result;
|
589
673
|
auto &bind_data = input.bind_data->Cast<TableScanBindData>();
|
590
674
|
result["Table"] = bind_data.table.name;
|
591
|
-
result["Type"] = bind_data.is_index_scan ? "Index Scan" : "
|
675
|
+
result["Type"] = bind_data.is_index_scan ? "Index Scan" : "Sequential Scan";
|
592
676
|
return result;
|
593
677
|
}
|
594
678
|
|
@@ -1,17 +1,17 @@
|
|
1
1
|
#ifndef DUCKDB_PATCH_VERSION
|
2
|
-
#define DUCKDB_PATCH_VERSION "
|
2
|
+
#define DUCKDB_PATCH_VERSION "0"
|
3
3
|
#endif
|
4
4
|
#ifndef DUCKDB_MINOR_VERSION
|
5
|
-
#define DUCKDB_MINOR_VERSION
|
5
|
+
#define DUCKDB_MINOR_VERSION 2
|
6
6
|
#endif
|
7
7
|
#ifndef DUCKDB_MAJOR_VERSION
|
8
8
|
#define DUCKDB_MAJOR_VERSION 1
|
9
9
|
#endif
|
10
10
|
#ifndef DUCKDB_VERSION
|
11
|
-
#define DUCKDB_VERSION "v1.
|
11
|
+
#define DUCKDB_VERSION "v1.2.0"
|
12
12
|
#endif
|
13
13
|
#ifndef DUCKDB_SOURCE_ID
|
14
|
-
#define DUCKDB_SOURCE_ID "
|
14
|
+
#define DUCKDB_SOURCE_ID "5f5512b827"
|
15
15
|
#endif
|
16
16
|
#include "duckdb/function/table/system_functions.hpp"
|
17
17
|
#include "duckdb/main/database.hpp"
|
@@ -194,7 +194,12 @@ static void ApplyWindowStats(const WindowBoundary &boundary, FrameDelta &delta,
|
|
194
194
|
case WindowBoundary::EXPR_PRECEDING_RANGE:
|
195
195
|
case WindowBoundary::EXPR_FOLLOWING_RANGE:
|
196
196
|
return;
|
197
|
-
|
197
|
+
case WindowBoundary::CURRENT_ROW_GROUPS:
|
198
|
+
case WindowBoundary::EXPR_PRECEDING_GROUPS:
|
199
|
+
case WindowBoundary::EXPR_FOLLOWING_GROUPS:
|
200
|
+
return;
|
201
|
+
case WindowBoundary::INVALID:
|
202
|
+
throw InternalException(is_start ? "Unknown window start boundary" : "Unknown window end boundary");
|
198
203
|
break;
|
199
204
|
}
|
200
205
|
|
@@ -374,7 +374,7 @@ WindowBoundsSet WindowBoundariesState::GetWindowBounds(const BoundWindowExpressi
|
|
374
374
|
result.insert(FRAME_END);
|
375
375
|
break;
|
376
376
|
default:
|
377
|
-
throw InternalException("Window
|
377
|
+
throw InternalException("Window expression type %s", ExpressionTypeToString(wexpr.GetExpressionType()));
|
378
378
|
}
|
379
379
|
|
380
380
|
// Internal dependencies
|
@@ -388,11 +388,12 @@ WindowBoundsSet WindowBoundariesState::GetWindowBounds(const BoundWindowExpressi
|
|
388
388
|
result.insert(PEER_END);
|
389
389
|
}
|
390
390
|
|
391
|
-
// If the frames are RANGE, then we need peer boundaries
|
392
|
-
// If they are preceding or following,
|
391
|
+
// If the frames are RANGE or GROUPS, then we need peer boundaries
|
392
|
+
// If they are preceding or following, RANGE also needs to know
|
393
393
|
// where the valid values begin or end.
|
394
394
|
switch (wexpr.start) {
|
395
395
|
case WindowBoundary::CURRENT_ROW_RANGE:
|
396
|
+
case WindowBoundary::CURRENT_ROW_GROUPS:
|
396
397
|
result.insert(PEER_BEGIN);
|
397
398
|
break;
|
398
399
|
case WindowBoundary::EXPR_PRECEDING_RANGE:
|
@@ -404,12 +405,24 @@ WindowBoundsSet WindowBoundariesState::GetWindowBounds(const BoundWindowExpressi
|
|
404
405
|
result.insert(PEER_BEGIN);
|
405
406
|
result.insert(VALID_END);
|
406
407
|
break;
|
407
|
-
|
408
|
+
case WindowBoundary::EXPR_PRECEDING_GROUPS:
|
409
|
+
result.insert(PEER_BEGIN);
|
410
|
+
break;
|
411
|
+
case WindowBoundary::EXPR_FOLLOWING_GROUPS:
|
412
|
+
result.insert(PEER_BEGIN);
|
413
|
+
break;
|
414
|
+
case WindowBoundary::UNBOUNDED_PRECEDING:
|
415
|
+
case WindowBoundary::UNBOUNDED_FOLLOWING:
|
416
|
+
case WindowBoundary::CURRENT_ROW_ROWS:
|
417
|
+
case WindowBoundary::EXPR_PRECEDING_ROWS:
|
418
|
+
case WindowBoundary::EXPR_FOLLOWING_ROWS:
|
419
|
+
case WindowBoundary::INVALID:
|
408
420
|
break;
|
409
421
|
}
|
410
422
|
|
411
423
|
switch (wexpr.end) {
|
412
424
|
case WindowBoundary::CURRENT_ROW_RANGE:
|
425
|
+
case WindowBoundary::CURRENT_ROW_GROUPS:
|
413
426
|
result.insert(PEER_END);
|
414
427
|
break;
|
415
428
|
case WindowBoundary::EXPR_PRECEDING_RANGE:
|
@@ -421,7 +434,18 @@ WindowBoundsSet WindowBoundariesState::GetWindowBounds(const BoundWindowExpressi
|
|
421
434
|
result.insert(VALID_BEGIN);
|
422
435
|
result.insert(VALID_END);
|
423
436
|
break;
|
424
|
-
|
437
|
+
case WindowBoundary::EXPR_PRECEDING_GROUPS:
|
438
|
+
result.insert(PEER_END);
|
439
|
+
break;
|
440
|
+
case WindowBoundary::EXPR_FOLLOWING_GROUPS:
|
441
|
+
result.insert(PEER_END);
|
442
|
+
break;
|
443
|
+
case WindowBoundary::UNBOUNDED_PRECEDING:
|
444
|
+
case WindowBoundary::UNBOUNDED_FOLLOWING:
|
445
|
+
case WindowBoundary::CURRENT_ROW_ROWS:
|
446
|
+
case WindowBoundary::EXPR_PRECEDING_ROWS:
|
447
|
+
case WindowBoundary::EXPR_FOLLOWING_ROWS:
|
448
|
+
case WindowBoundary::INVALID:
|
425
449
|
break;
|
426
450
|
}
|
427
451
|
}
|
@@ -483,10 +507,10 @@ void WindowBoundariesState::Bounds(DataChunk &bounds, idx_t row_idx, optional_pt
|
|
483
507
|
ValidEnd(bounds, row_idx, count, is_jump, partition_mask, order_mask, range);
|
484
508
|
}
|
485
509
|
if (required.count(FRAME_BEGIN)) {
|
486
|
-
FrameBegin(bounds, row_idx, count, boundary_start, range);
|
510
|
+
FrameBegin(bounds, row_idx, count, boundary_start, order_mask, range);
|
487
511
|
}
|
488
512
|
if (required.count(FRAME_END)) {
|
489
|
-
FrameEnd(bounds, row_idx, count, boundary_end, range);
|
513
|
+
FrameEnd(bounds, row_idx, count, boundary_end, order_mask, range);
|
490
514
|
}
|
491
515
|
next_pos += count;
|
492
516
|
|
@@ -683,7 +707,8 @@ void WindowBoundariesState::ValidEnd(DataChunk &bounds, idx_t row_idx, const idx
|
|
683
707
|
}
|
684
708
|
|
685
709
|
void WindowBoundariesState::FrameBegin(DataChunk &bounds, idx_t row_idx, const idx_t count,
|
686
|
-
WindowInputExpression &boundary_begin,
|
710
|
+
WindowInputExpression &boundary_begin, const ValidityMask &order_mask,
|
711
|
+
optional_ptr<WindowCursor> range) {
|
687
712
|
auto partition_begin_data = FlatVector::GetData<idx_t>(bounds.data[PARTITION_BEGIN]);
|
688
713
|
auto partition_end_data = FlatVector::GetData<const idx_t>(bounds.data[PARTITION_END]);
|
689
714
|
auto peer_begin_data = FlatVector::GetData<idx_t>(bounds.data[PEER_BEGIN]);
|
@@ -704,6 +729,9 @@ void WindowBoundariesState::FrameBegin(DataChunk &bounds, idx_t row_idx, const i
|
|
704
729
|
}
|
705
730
|
break;
|
706
731
|
case WindowBoundary::CURRENT_ROW_RANGE:
|
732
|
+
case WindowBoundary::CURRENT_ROW_GROUPS:
|
733
|
+
// in RANGE or GROUPS mode it means that the frame starts or ends with the current row's
|
734
|
+
// first or last peer in the ORDER BY ordering
|
707
735
|
bounds.data[FRAME_BEGIN].Reference(bounds.data[PEER_BEGIN]);
|
708
736
|
frame_begin_data = peer_begin_data;
|
709
737
|
break;
|
@@ -759,7 +787,53 @@ void WindowBoundariesState::FrameBegin(DataChunk &bounds, idx_t row_idx, const i
|
|
759
787
|
frame_begin_data[chunk_idx] = window_start;
|
760
788
|
}
|
761
789
|
break;
|
762
|
-
|
790
|
+
case WindowBoundary::EXPR_PRECEDING_GROUPS:
|
791
|
+
// In GROUPS mode, the offset is an integer indicating that the frame starts or ends that many peer groups
|
792
|
+
// before or after the current row's peer group, where a peer group is a group of rows that are equivalent
|
793
|
+
// according to the window's ORDER BY clause.
|
794
|
+
for (idx_t chunk_idx = 0; chunk_idx < count; ++chunk_idx, ++row_idx) {
|
795
|
+
if (boundary_begin.CellIsNull(chunk_idx)) {
|
796
|
+
window_start = peer_begin_data[chunk_idx];
|
797
|
+
} else {
|
798
|
+
// Count peer groups backwards.
|
799
|
+
const auto peer_begin = peer_begin_data[chunk_idx];
|
800
|
+
const auto partition_begin = partition_begin_data[chunk_idx];
|
801
|
+
const auto boundary = boundary_begin.GetCell<int64_t>(chunk_idx);
|
802
|
+
if (boundary < 0) {
|
803
|
+
throw OutOfRangeException("Invalid GROUPS PRECEDING value");
|
804
|
+
} else if (!boundary) {
|
805
|
+
window_start = peer_begin;
|
806
|
+
} else {
|
807
|
+
auto n = UnsafeNumericCast<idx_t>(boundary);
|
808
|
+
window_start = FindPrevStart(order_mask, partition_begin, peer_begin, n);
|
809
|
+
}
|
810
|
+
}
|
811
|
+
frame_begin_data[chunk_idx] = window_start;
|
812
|
+
}
|
813
|
+
break;
|
814
|
+
case WindowBoundary::EXPR_FOLLOWING_GROUPS:
|
815
|
+
for (idx_t chunk_idx = 0; chunk_idx < count; ++chunk_idx, ++row_idx) {
|
816
|
+
if (boundary_begin.CellIsNull(chunk_idx)) {
|
817
|
+
window_start = peer_begin_data[chunk_idx];
|
818
|
+
} else {
|
819
|
+
// Count peer groups forward.
|
820
|
+
const auto peer_begin = peer_begin_data[chunk_idx];
|
821
|
+
const auto partition_end = partition_end_data[chunk_idx];
|
822
|
+
const auto boundary = boundary_begin.GetCell<int64_t>(chunk_idx);
|
823
|
+
if (boundary < 0) {
|
824
|
+
throw OutOfRangeException("Invalid GROUPS FOLLOWING value");
|
825
|
+
} else if (!boundary) {
|
826
|
+
window_start = peer_begin;
|
827
|
+
} else {
|
828
|
+
auto n = UnsafeNumericCast<idx_t>(boundary);
|
829
|
+
window_start = FindNextStart(order_mask, peer_begin + 1, partition_end, n);
|
830
|
+
}
|
831
|
+
}
|
832
|
+
frame_begin_data[chunk_idx] = window_start;
|
833
|
+
}
|
834
|
+
break;
|
835
|
+
case WindowBoundary::UNBOUNDED_FOLLOWING:
|
836
|
+
case WindowBoundary::INVALID:
|
763
837
|
throw InternalException("Unsupported window start boundary");
|
764
838
|
}
|
765
839
|
|
@@ -767,7 +841,8 @@ void WindowBoundariesState::FrameBegin(DataChunk &bounds, idx_t row_idx, const i
|
|
767
841
|
}
|
768
842
|
|
769
843
|
void WindowBoundariesState::FrameEnd(DataChunk &bounds, idx_t row_idx, const idx_t count,
|
770
|
-
WindowInputExpression &boundary_end,
|
844
|
+
WindowInputExpression &boundary_end, const ValidityMask &order_mask,
|
845
|
+
optional_ptr<WindowCursor> range) {
|
771
846
|
auto partition_begin_data = FlatVector::GetData<const idx_t>(bounds.data[PARTITION_BEGIN]);
|
772
847
|
auto partition_end_data = FlatVector::GetData<idx_t>(bounds.data[PARTITION_END]);
|
773
848
|
auto peer_end_data = FlatVector::GetData<idx_t>(bounds.data[PEER_END]);
|
@@ -784,6 +859,9 @@ void WindowBoundariesState::FrameEnd(DataChunk &bounds, idx_t row_idx, const idx
|
|
784
859
|
}
|
785
860
|
break;
|
786
861
|
case WindowBoundary::CURRENT_ROW_RANGE:
|
862
|
+
case WindowBoundary::CURRENT_ROW_GROUPS:
|
863
|
+
// in RANGE or GROUPS mode it means that the frame starts or ends with the current row's
|
864
|
+
// first or last peer in the ORDER BY ordering
|
787
865
|
bounds.data[FRAME_END].Reference(bounds.data[PEER_END]);
|
788
866
|
frame_end_data = peer_end_data;
|
789
867
|
break;
|
@@ -844,7 +922,53 @@ void WindowBoundariesState::FrameEnd(DataChunk &bounds, idx_t row_idx, const idx
|
|
844
922
|
frame_end_data[chunk_idx] = window_end;
|
845
923
|
}
|
846
924
|
break;
|
847
|
-
|
925
|
+
case WindowBoundary::EXPR_PRECEDING_GROUPS:
|
926
|
+
// In GROUPS mode, the offset is an integer indicating that the frame starts or ends that many peer groups
|
927
|
+
// before or after the current row's peer group, where a peer group is a group of rows that are equivalent
|
928
|
+
// according to the window's ORDER BY clause.
|
929
|
+
for (idx_t chunk_idx = 0; chunk_idx < count; ++chunk_idx, ++row_idx) {
|
930
|
+
if (boundary_end.CellIsNull(chunk_idx)) {
|
931
|
+
window_end = peer_end_data[chunk_idx];
|
932
|
+
} else {
|
933
|
+
// Count peer groups backwards.
|
934
|
+
const auto peer_end = peer_end_data[chunk_idx];
|
935
|
+
const auto partition_begin = partition_begin_data[chunk_idx];
|
936
|
+
const auto boundary = boundary_end.GetCell<int64_t>(chunk_idx);
|
937
|
+
if (boundary < 0) {
|
938
|
+
throw OutOfRangeException("Invalid GROUPS PRECEDING value");
|
939
|
+
} else if (!boundary) {
|
940
|
+
window_end = peer_end;
|
941
|
+
} else {
|
942
|
+
auto n = UnsafeNumericCast<idx_t>(boundary);
|
943
|
+
window_end = FindPrevStart(order_mask, partition_begin, peer_end, n);
|
944
|
+
}
|
945
|
+
}
|
946
|
+
frame_end_data[chunk_idx] = window_end;
|
947
|
+
}
|
948
|
+
break;
|
949
|
+
case WindowBoundary::EXPR_FOLLOWING_GROUPS:
|
950
|
+
for (idx_t chunk_idx = 0; chunk_idx < count; ++chunk_idx, ++row_idx) {
|
951
|
+
if (boundary_end.CellIsNull(chunk_idx)) {
|
952
|
+
window_end = peer_end_data[chunk_idx];
|
953
|
+
} else {
|
954
|
+
// Count peer groups forward.
|
955
|
+
const auto peer_end = peer_end_data[chunk_idx];
|
956
|
+
const auto partition_end = partition_end_data[chunk_idx];
|
957
|
+
const auto boundary = boundary_end.GetCell<int64_t>(chunk_idx);
|
958
|
+
if (boundary < 0) {
|
959
|
+
throw OutOfRangeException("Invalid GROUPS FOLLOWING value");
|
960
|
+
} else if (!boundary) {
|
961
|
+
window_end = peer_end;
|
962
|
+
} else {
|
963
|
+
auto n = UnsafeNumericCast<idx_t>(boundary);
|
964
|
+
window_end = FindNextStart(order_mask, peer_end + 1, partition_end, n);
|
965
|
+
}
|
966
|
+
}
|
967
|
+
frame_end_data[chunk_idx] = window_end;
|
968
|
+
}
|
969
|
+
break;
|
970
|
+
case WindowBoundary::UNBOUNDED_PRECEDING:
|
971
|
+
case WindowBoundary::INVALID:
|
848
972
|
throw InternalException("Unsupported window end boundary");
|
849
973
|
}
|
850
974
|
|