duckdb 0.7.1-dev2.0 → 0.7.1-dev284.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binding.gyp +7 -7
- package/package.json +1 -1
- package/src/duckdb/extension/json/buffered_json_reader.cpp +50 -9
- package/src/duckdb/extension/json/include/buffered_json_reader.hpp +7 -2
- package/src/duckdb/extension/json/include/json_common.hpp +2 -2
- package/src/duckdb/extension/json/include/json_scan.hpp +29 -10
- package/src/duckdb/extension/json/json_functions/copy_json.cpp +35 -22
- package/src/duckdb/extension/json/json_functions/json_create.cpp +8 -8
- package/src/duckdb/extension/json/json_functions/json_transform.cpp +47 -8
- package/src/duckdb/extension/json/json_functions/read_json.cpp +104 -49
- package/src/duckdb/extension/json/json_functions/read_json_objects.cpp +5 -3
- package/src/duckdb/extension/json/json_functions.cpp +6 -0
- package/src/duckdb/extension/json/json_scan.cpp +144 -34
- package/src/duckdb/extension/parquet/parquet-extension.cpp +3 -2
- package/src/duckdb/src/catalog/catalog.cpp +15 -0
- package/src/duckdb/src/catalog/catalog_entry/index_catalog_entry.cpp +8 -7
- package/src/duckdb/src/common/enums/logical_operator_type.cpp +2 -0
- package/src/duckdb/src/common/enums/physical_operator_type.cpp +2 -0
- package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
- package/src/duckdb/src/common/file_system.cpp +14 -0
- package/src/duckdb/src/common/hive_partitioning.cpp +1 -0
- package/src/duckdb/src/common/operator/cast_operators.cpp +14 -8
- package/src/duckdb/src/common/printer.cpp +1 -1
- package/src/duckdb/src/common/types/time.cpp +1 -1
- package/src/duckdb/src/common/types/timestamp.cpp +35 -4
- package/src/duckdb/src/common/types.cpp +36 -10
- package/src/duckdb/src/execution/column_binding_resolver.cpp +5 -2
- package/src/duckdb/src/execution/index/art/art.cpp +117 -67
- package/src/duckdb/src/execution/index/art/art_key.cpp +24 -12
- package/src/duckdb/src/execution/index/art/leaf.cpp +7 -8
- package/src/duckdb/src/execution/index/art/node.cpp +13 -27
- package/src/duckdb/src/execution/index/art/node16.cpp +5 -8
- package/src/duckdb/src/execution/index/art/node256.cpp +3 -5
- package/src/duckdb/src/execution/index/art/node4.cpp +4 -7
- package/src/duckdb/src/execution/index/art/node48.cpp +5 -8
- package/src/duckdb/src/execution/index/art/prefix.cpp +2 -3
- package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +7 -9
- package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +6 -11
- package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +13 -13
- package/src/duckdb/src/execution/operator/persistent/parallel_csv_reader.cpp +1 -1
- package/src/duckdb/src/execution/operator/schema/physical_detach.cpp +37 -0
- package/src/duckdb/src/execution/operator/schema/physical_drop.cpp +0 -5
- package/src/duckdb/src/execution/physical_plan/plan_simple.cpp +4 -0
- package/src/duckdb/src/execution/physical_plan_generator.cpp +1 -0
- package/src/duckdb/src/function/pragma/pragma_queries.cpp +38 -11
- package/src/duckdb/src/function/table/read_csv.cpp +17 -5
- package/src/duckdb/src/function/table/table_scan.cpp +3 -0
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +5 -1
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_index_entry.hpp +1 -1
- package/src/duckdb/src/include/duckdb/catalog/catalog_entry/index_catalog_entry.hpp +1 -1
- package/src/duckdb/src/include/duckdb/common/enums/logical_operator_type.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/enums/physical_operator_type.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +3 -2
- package/src/duckdb/src/include/duckdb/common/enums/wal_type.hpp +3 -0
- package/src/duckdb/src/include/duckdb/common/exception.hpp +10 -0
- package/src/duckdb/src/include/duckdb/common/file_system.hpp +1 -0
- package/src/duckdb/src/include/duckdb/common/hive_partitioning.hpp +9 -1
- package/src/duckdb/src/include/duckdb/common/radix_partitioning.hpp +4 -4
- package/src/duckdb/src/include/duckdb/common/types/timestamp.hpp +5 -1
- package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +37 -41
- package/src/duckdb/src/include/duckdb/execution/index/art/art_key.hpp +8 -11
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/base_csv_reader.hpp +1 -3
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/buffered_csv_reader.hpp +0 -2
- package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +2 -0
- package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_detach.hpp +32 -0
- package/src/duckdb/src/include/duckdb/main/client_data.hpp +2 -2
- package/src/duckdb/src/include/duckdb/main/config.hpp +0 -3
- package/src/duckdb/src/include/duckdb/parser/parsed_data/create_database_info.hpp +0 -4
- package/src/duckdb/src/include/duckdb/parser/parsed_data/detach_info.hpp +32 -0
- package/src/duckdb/src/include/duckdb/parser/query_node/select_node.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/sql_statement.hpp +2 -2
- package/src/duckdb/src/include/duckdb/parser/statement/copy_statement.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/statement/detach_statement.hpp +29 -0
- package/src/duckdb/src/include/duckdb/parser/statement/list.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/statement/select_statement.hpp +3 -3
- package/src/duckdb/src/include/duckdb/parser/tableref/subqueryref.hpp +1 -1
- package/src/duckdb/src/include/duckdb/parser/tokens.hpp +1 -0
- package/src/duckdb/src/include/duckdb/parser/transformer.hpp +1 -0
- package/src/duckdb/src/include/duckdb/planner/binder.hpp +4 -0
- package/src/duckdb/src/include/duckdb/planner/expression_binder/index_binder.hpp +10 -3
- package/src/duckdb/src/include/duckdb/planner/operator/logical_execute.hpp +1 -5
- package/src/duckdb/src/include/duckdb/planner/operator/logical_show.hpp +1 -2
- package/src/duckdb/src/include/duckdb/storage/data_table.hpp +7 -1
- package/src/duckdb/src/include/duckdb/storage/index.hpp +47 -38
- package/src/duckdb/src/include/duckdb/storage/storage_extension.hpp +7 -0
- package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -0
- package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +7 -0
- package/src/duckdb/src/main/client_context.cpp +2 -0
- package/src/duckdb/src/main/extension/extension_alias.cpp +2 -1
- package/src/duckdb/src/optimizer/statistics/operator/propagate_join.cpp +2 -6
- package/src/duckdb/src/parser/parsed_data/create_index_info.cpp +3 -0
- package/src/duckdb/src/parser/statement/copy_statement.cpp +2 -13
- package/src/duckdb/src/parser/statement/delete_statement.cpp +3 -0
- package/src/duckdb/src/parser/statement/detach_statement.cpp +15 -0
- package/src/duckdb/src/parser/statement/insert_statement.cpp +9 -0
- package/src/duckdb/src/parser/statement/update_statement.cpp +3 -0
- package/src/duckdb/src/parser/transform/expression/transform_case.cpp +3 -3
- package/src/duckdb/src/parser/transform/statement/transform_create_database.cpp +0 -1
- package/src/duckdb/src/parser/transform/statement/transform_detach.cpp +19 -0
- package/src/duckdb/src/parser/transformer.cpp +2 -0
- package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +3 -0
- package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +6 -3
- package/src/duckdb/src/planner/binder/statement/bind_create.cpp +16 -14
- package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +13 -0
- package/src/duckdb/src/planner/binder/statement/bind_detach.cpp +19 -0
- package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +29 -4
- package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +22 -1
- package/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp +2 -1
- package/src/duckdb/src/planner/binder.cpp +2 -0
- package/src/duckdb/src/planner/expression_binder/index_binder.cpp +32 -1
- package/src/duckdb/src/planner/expression_binder/lateral_binder.cpp +21 -5
- package/src/duckdb/src/planner/logical_operator.cpp +4 -0
- package/src/duckdb/src/planner/planner.cpp +1 -0
- package/src/duckdb/src/storage/compression/bitpacking.cpp +16 -7
- package/src/duckdb/src/storage/data_table.cpp +66 -3
- package/src/duckdb/src/storage/index.cpp +1 -1
- package/src/duckdb/src/storage/local_storage.cpp +1 -1
- package/src/duckdb/src/storage/storage_info.cpp +2 -1
- package/src/duckdb/src/storage/table/column_data.cpp +4 -2
- package/src/duckdb/src/storage/table/update_segment.cpp +15 -0
- package/src/duckdb/src/storage/table_index_list.cpp +1 -2
- package/src/duckdb/src/storage/wal_replay.cpp +68 -0
- package/src/duckdb/src/storage/write_ahead_log.cpp +21 -1
- package/src/duckdb/src/transaction/commit_state.cpp +5 -2
- package/src/duckdb/third_party/fmt/include/fmt/core.h +1 -2
- package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +1 -0
- package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +14 -0
- package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +530 -1006
- package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +17659 -17626
- package/src/duckdb/third_party/thrift/thrift/Thrift.h +8 -2
- package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
- package/src/duckdb/ub_src_execution_operator_schema.cpp +2 -0
- package/src/duckdb/ub_src_parser_statement.cpp +2 -0
- package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
- package/src/duckdb/ub_src_planner_binder_statement.cpp +2 -0
- package/src/statement.cpp +46 -12
- package/test/prepare.test.ts +39 -1
- package/test/typescript_decls.test.ts +1 -1
- package/src/duckdb/src/include/duckdb/function/create_database_extension.hpp +0 -37
|
@@ -97,17 +97,20 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt) {
|
|
|
97
97
|
for (auto &option : original_options) {
|
|
98
98
|
auto loption = StringUtil::Lower(option.first);
|
|
99
99
|
if (loption == "use_tmp_file") {
|
|
100
|
-
use_tmp_file =
|
|
100
|
+
use_tmp_file =
|
|
101
|
+
option.second.empty() || option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue<bool>();
|
|
101
102
|
user_set_use_tmp_file = true;
|
|
102
103
|
continue;
|
|
103
104
|
}
|
|
104
105
|
if (loption == "allow_overwrite") {
|
|
105
|
-
allow_overwrite =
|
|
106
|
+
allow_overwrite =
|
|
107
|
+
option.second.empty() || option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue<bool>();
|
|
106
108
|
continue;
|
|
107
109
|
}
|
|
108
110
|
|
|
109
111
|
if (loption == "per_thread_output") {
|
|
110
|
-
per_thread_output =
|
|
112
|
+
per_thread_output =
|
|
113
|
+
option.second.empty() || option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue<bool>();
|
|
111
114
|
continue;
|
|
112
115
|
}
|
|
113
116
|
if (loption == "partition_by") {
|
|
@@ -12,13 +12,11 @@
|
|
|
12
12
|
#include "duckdb/parser/parsed_data/create_macro_info.hpp"
|
|
13
13
|
#include "duckdb/parser/parsed_data/create_view_info.hpp"
|
|
14
14
|
#include "duckdb/parser/parsed_data/create_database_info.hpp"
|
|
15
|
-
#include "duckdb/function/create_database_extension.hpp"
|
|
16
15
|
#include "duckdb/parser/tableref/table_function_ref.hpp"
|
|
17
16
|
#include "duckdb/parser/parsed_expression_iterator.hpp"
|
|
18
17
|
#include "duckdb/parser/statement/create_statement.hpp"
|
|
19
18
|
#include "duckdb/planner/binder.hpp"
|
|
20
19
|
#include "duckdb/planner/bound_query_node.hpp"
|
|
21
|
-
#include "duckdb/planner/expression_binder/aggregate_binder.hpp"
|
|
22
20
|
#include "duckdb/planner/expression_binder/index_binder.hpp"
|
|
23
21
|
#include "duckdb/planner/expression_binder/select_binder.hpp"
|
|
24
22
|
#include "duckdb/planner/operator/logical_create.hpp"
|
|
@@ -26,13 +24,13 @@
|
|
|
26
24
|
#include "duckdb/planner/operator/logical_create_table.hpp"
|
|
27
25
|
#include "duckdb/planner/operator/logical_get.hpp"
|
|
28
26
|
#include "duckdb/planner/operator/logical_distinct.hpp"
|
|
29
|
-
#include "duckdb/planner/parsed_data/bound_create_function_info.hpp"
|
|
30
27
|
#include "duckdb/planner/parsed_data/bound_create_table_info.hpp"
|
|
31
28
|
#include "duckdb/planner/query_node/bound_select_node.hpp"
|
|
32
29
|
#include "duckdb/planner/tableref/bound_basetableref.hpp"
|
|
33
30
|
#include "duckdb/parser/constraints/foreign_key_constraint.hpp"
|
|
34
31
|
#include "duckdb/function/scalar_macro_function.hpp"
|
|
35
32
|
#include "duckdb/storage/data_table.hpp"
|
|
33
|
+
#include "duckdb/storage/storage_extension.hpp"
|
|
36
34
|
#include "duckdb/main/client_data.hpp"
|
|
37
35
|
#include "duckdb/parser/constraints/unique_constraint.hpp"
|
|
38
36
|
#include "duckdb/parser/constraints/list.hpp"
|
|
@@ -651,23 +649,27 @@ BoundStatement Binder::Bind(CreateStatement &stmt) {
|
|
|
651
649
|
case CatalogType::DATABASE_ENTRY: {
|
|
652
650
|
// not supported in DuckDB yet but allow extensions to intercept and implement this functionality
|
|
653
651
|
auto &base = (CreateDatabaseInfo &)*stmt.info;
|
|
654
|
-
string extension_name = base.extension_name;
|
|
655
652
|
string database_name = base.name;
|
|
656
653
|
string source_path = base.path;
|
|
657
654
|
|
|
658
655
|
auto &config = DBConfig::GetConfig(context);
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
extension.function(context, extension_name, database_name, source_path, extension.data.get());
|
|
662
|
-
if (create_database_function_ref) {
|
|
663
|
-
auto bound_create_database_func = Bind(*create_database_function_ref);
|
|
664
|
-
result.plan = CreatePlan(*bound_create_database_func);
|
|
665
|
-
break;
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
if (!result.plan) {
|
|
656
|
+
|
|
657
|
+
if (config.storage_extensions.empty()) {
|
|
669
658
|
throw NotImplementedException("CREATE DATABASE not supported in DuckDB yet");
|
|
670
659
|
}
|
|
660
|
+
// for now assume only one storage extension provides the custom create_database impl
|
|
661
|
+
for (auto &extension_entry : config.storage_extensions) {
|
|
662
|
+
if (extension_entry.second->create_database != nullptr) {
|
|
663
|
+
auto &storage_extension = extension_entry.second;
|
|
664
|
+
auto create_database_function_ref = storage_extension->create_database(
|
|
665
|
+
storage_extension->storage_info.get(), context, database_name, source_path);
|
|
666
|
+
if (create_database_function_ref) {
|
|
667
|
+
auto bound_create_database_func = Bind(*create_database_function_ref);
|
|
668
|
+
result.plan = CreatePlan(*bound_create_database_func);
|
|
669
|
+
break;
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
}
|
|
671
673
|
break;
|
|
672
674
|
}
|
|
673
675
|
default:
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
#include "duckdb/parser/expression/list.hpp"
|
|
17
17
|
#include "duckdb/common/index_map.hpp"
|
|
18
18
|
#include "duckdb/planner/expression_iterator.hpp"
|
|
19
|
+
#include "duckdb/planner/expression_binder/index_binder.hpp"
|
|
20
|
+
#include "duckdb/parser/parsed_data/create_index_info.hpp"
|
|
19
21
|
|
|
20
22
|
#include <algorithm>
|
|
21
23
|
|
|
@@ -300,4 +302,15 @@ unique_ptr<BoundCreateTableInfo> Binder::BindCreateTableInfo(unique_ptr<CreateIn
|
|
|
300
302
|
return BindCreateTableInfo(std::move(info), schema);
|
|
301
303
|
}
|
|
302
304
|
|
|
305
|
+
vector<unique_ptr<Expression>> Binder::BindCreateIndexExpressions(TableCatalogEntry *table, CreateIndexInfo *info) {
|
|
306
|
+
vector<unique_ptr<Expression>> expressions;
|
|
307
|
+
|
|
308
|
+
auto index_binder = IndexBinder(*this, this->context, table, info);
|
|
309
|
+
for (auto &expr : info->expressions) {
|
|
310
|
+
expressions.push_back(index_binder.Bind(expr));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return expressions;
|
|
314
|
+
}
|
|
315
|
+
|
|
303
316
|
} // namespace duckdb
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#include "duckdb/parser/statement/detach_statement.hpp"
|
|
2
|
+
#include "duckdb/planner/binder.hpp"
|
|
3
|
+
#include "duckdb/planner/operator/logical_simple.hpp"
|
|
4
|
+
#include "duckdb/main/config.hpp"
|
|
5
|
+
|
|
6
|
+
namespace duckdb {
|
|
7
|
+
|
|
8
|
+
BoundStatement Binder::Bind(DetachStatement &stmt) {
|
|
9
|
+
BoundStatement result;
|
|
10
|
+
|
|
11
|
+
result.plan = make_unique<LogicalSimple>(LogicalOperatorType::LOGICAL_DETACH, std::move(stmt.info));
|
|
12
|
+
result.names = {"Success"};
|
|
13
|
+
result.types = {LogicalType::BOOLEAN};
|
|
14
|
+
properties.allow_stream_result = false;
|
|
15
|
+
properties.return_type = StatementReturnType::NOTHING;
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
} // namespace duckdb
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
#include "duckdb/parser/statement/drop_statement.hpp"
|
|
2
2
|
#include "duckdb/planner/binder.hpp"
|
|
3
|
+
#include "duckdb/planner/bound_tableref.hpp"
|
|
3
4
|
#include "duckdb/planner/operator/logical_simple.hpp"
|
|
4
5
|
#include "duckdb/catalog/catalog.hpp"
|
|
5
6
|
#include "duckdb/catalog/standard_entry.hpp"
|
|
6
7
|
#include "duckdb/catalog/catalog_entry/schema_catalog_entry.hpp"
|
|
8
|
+
#include "duckdb/parser/parsed_data/drop_info.hpp"
|
|
9
|
+
#include "duckdb/main/config.hpp"
|
|
10
|
+
#include "duckdb/storage/storage_extension.hpp"
|
|
7
11
|
|
|
8
12
|
namespace duckdb {
|
|
9
13
|
|
|
@@ -43,10 +47,31 @@ BoundStatement Binder::Bind(DropStatement &stmt) {
|
|
|
43
47
|
stmt.info->schema = entry->schema->name;
|
|
44
48
|
break;
|
|
45
49
|
}
|
|
46
|
-
case CatalogType::DATABASE_ENTRY:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
case CatalogType::DATABASE_ENTRY: {
|
|
51
|
+
auto &base = (DropInfo &)*stmt.info;
|
|
52
|
+
string database_name = base.name;
|
|
53
|
+
|
|
54
|
+
auto &config = DBConfig::GetConfig(context);
|
|
55
|
+
// for now assume only one storage extension provides the custom drop_database impl
|
|
56
|
+
for (auto &extension_entry : config.storage_extensions) {
|
|
57
|
+
if (extension_entry.second->drop_database != nullptr) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
auto &storage_extension = extension_entry.second;
|
|
61
|
+
auto drop_database_function_ref =
|
|
62
|
+
storage_extension->drop_database(storage_extension->storage_info.get(), context, database_name);
|
|
63
|
+
if (drop_database_function_ref) {
|
|
64
|
+
auto bound_drop_database_func = Bind(*drop_database_function_ref);
|
|
65
|
+
result.plan = CreatePlan(*bound_drop_database_func);
|
|
66
|
+
result.names = {"Success"};
|
|
67
|
+
result.types = {LogicalType::BOOLEAN};
|
|
68
|
+
properties.allow_stream_result = false;
|
|
69
|
+
properties.return_type = StatementReturnType::NOTHING;
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
throw BinderException("Drop is not supported for this database!");
|
|
74
|
+
}
|
|
50
75
|
default:
|
|
51
76
|
throw BinderException("Unknown catalog type for drop statement!");
|
|
52
77
|
}
|
|
@@ -301,7 +301,28 @@ void Binder::BindOnConflictClause(LogicalInsert &insert, TableCatalogEntry &tabl
|
|
|
301
301
|
insert.on_conflict_condition = std::move(condition);
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
-
auto
|
|
304
|
+
auto bindings = insert.children[0]->GetColumnBindings();
|
|
305
|
+
idx_t projection_index = DConstants::INVALID_INDEX;
|
|
306
|
+
std::vector<unique_ptr<LogicalOperator>> *insert_child_operators;
|
|
307
|
+
insert_child_operators = &insert.children;
|
|
308
|
+
while (projection_index == DConstants::INVALID_INDEX) {
|
|
309
|
+
if (insert_child_operators->empty()) {
|
|
310
|
+
// No further children to visit
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
D_ASSERT(insert_child_operators->size() >= 1);
|
|
314
|
+
auto ¤t_child = (*insert_child_operators)[0];
|
|
315
|
+
auto table_indices = current_child->GetTableIndex();
|
|
316
|
+
if (table_indices.empty()) {
|
|
317
|
+
// This operator does not have a table index to refer to, we have to visit its children
|
|
318
|
+
insert_child_operators = ¤t_child->children;
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
projection_index = table_indices[0];
|
|
322
|
+
}
|
|
323
|
+
if (projection_index == DConstants::INVALID_INDEX) {
|
|
324
|
+
throw InternalException("Could not locate a table_index from the children of the insert");
|
|
325
|
+
}
|
|
305
326
|
|
|
306
327
|
string unused;
|
|
307
328
|
auto original_binding = bind_context.GetBinding(table_alias, unused);
|
|
@@ -128,6 +128,8 @@ unique_ptr<BoundTableRef> Binder::Bind(JoinRef &ref) {
|
|
|
128
128
|
{
|
|
129
129
|
LateralBinder binder(left_binder, context);
|
|
130
130
|
result->right = right_binder.Bind(*ref.right);
|
|
131
|
+
result->correlated_columns = binder.ExtractCorrelatedColumns(right_binder);
|
|
132
|
+
|
|
131
133
|
result->lateral = binder.HasCorrelatedColumns();
|
|
132
134
|
if (result->lateral) {
|
|
133
135
|
// lateral join: can only be an INNER or LEFT join
|
|
@@ -135,7 +137,6 @@ unique_ptr<BoundTableRef> Binder::Bind(JoinRef &ref) {
|
|
|
135
137
|
throw BinderException("The combining JOIN type must be INNER or LEFT for a LATERAL reference");
|
|
136
138
|
}
|
|
137
139
|
}
|
|
138
|
-
result->correlated_columns = binder.ExtractCorrelatedColumns(right_binder);
|
|
139
140
|
}
|
|
140
141
|
|
|
141
142
|
vector<unique_ptr<ParsedExpression>> extra_conditions;
|
|
@@ -90,6 +90,8 @@ BoundStatement Binder::Bind(SQLStatement &statement) {
|
|
|
90
90
|
return Bind((LogicalPlanStatement &)statement);
|
|
91
91
|
case StatementType::ATTACH_STATEMENT:
|
|
92
92
|
return Bind((AttachStatement &)statement);
|
|
93
|
+
case StatementType::DETACH_STATEMENT:
|
|
94
|
+
return Bind((DetachStatement &)statement);
|
|
93
95
|
default: // LCOV_EXCL_START
|
|
94
96
|
throw NotImplementedException("Unimplemented statement type \"%s\" for Bind",
|
|
95
97
|
StatementTypeToString(statement.type));
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
#include "duckdb/planner/expression_binder/index_binder.hpp"
|
|
2
2
|
|
|
3
|
+
#include "duckdb/parser/parsed_data/create_index_info.hpp"
|
|
4
|
+
#include "duckdb/parser/expression/columnref_expression.hpp"
|
|
5
|
+
#include "duckdb/planner/expression/bound_columnref_expression.hpp"
|
|
6
|
+
#include "duckdb/planner/column_binding.hpp"
|
|
7
|
+
|
|
3
8
|
namespace duckdb {
|
|
4
9
|
|
|
5
|
-
IndexBinder::IndexBinder(Binder &binder, ClientContext &context
|
|
10
|
+
IndexBinder::IndexBinder(Binder &binder, ClientContext &context, TableCatalogEntry *table, CreateIndexInfo *info)
|
|
11
|
+
: ExpressionBinder(binder, context), table(table), info(info) {
|
|
6
12
|
}
|
|
7
13
|
|
|
8
14
|
BindResult IndexBinder::BindExpression(unique_ptr<ParsedExpression> *expr_ptr, idx_t depth, bool root_expression) {
|
|
@@ -12,6 +18,31 @@ BindResult IndexBinder::BindExpression(unique_ptr<ParsedExpression> *expr_ptr, i
|
|
|
12
18
|
return BindResult("window functions are not allowed in index expressions");
|
|
13
19
|
case ExpressionClass::SUBQUERY:
|
|
14
20
|
return BindResult("cannot use subquery in index expressions");
|
|
21
|
+
case ExpressionClass::COLUMN_REF: {
|
|
22
|
+
if (table) {
|
|
23
|
+
// WAL replay
|
|
24
|
+
// we assume that the parsed expressions have qualified column names
|
|
25
|
+
// and that the columns exist in the table
|
|
26
|
+
auto &col_ref = (ColumnRefExpression &)expr;
|
|
27
|
+
auto col_idx = table->GetColumnIndex(col_ref.column_names.back());
|
|
28
|
+
auto col_type = table->GetColumn(col_idx).GetType();
|
|
29
|
+
|
|
30
|
+
// find the col_idx in the index.column_ids
|
|
31
|
+
auto col_id_idx = DConstants::INVALID_INDEX;
|
|
32
|
+
for (idx_t i = 0; i < info->column_ids.size(); i++) {
|
|
33
|
+
if (col_idx.index == info->column_ids[i]) {
|
|
34
|
+
col_id_idx = i;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (col_id_idx == DConstants::INVALID_INDEX) {
|
|
39
|
+
throw InternalException("failed to replay CREATE INDEX statement - column id not found");
|
|
40
|
+
}
|
|
41
|
+
return BindResult(
|
|
42
|
+
make_unique<BoundColumnRefExpression>(col_ref.alias, col_type, ColumnBinding(0, col_id_idx)));
|
|
43
|
+
}
|
|
44
|
+
return ExpressionBinder::BindExpression(expr_ptr, depth);
|
|
45
|
+
}
|
|
15
46
|
default:
|
|
16
47
|
return ExpressionBinder::BindExpression(expr_ptr, depth);
|
|
17
48
|
}
|
|
@@ -39,14 +39,30 @@ BindResult LateralBinder::BindColumnRef(unique_ptr<ParsedExpression> *expr_ptr,
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
vector<CorrelatedColumnInfo> LateralBinder::ExtractCorrelatedColumns(Binder &binder) {
|
|
42
|
+
|
|
43
|
+
if (correlated_columns.empty()) {
|
|
44
|
+
return binder.correlated_columns;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// clear outer
|
|
48
|
+
correlated_columns.clear();
|
|
42
49
|
auto all_correlated_columns = binder.correlated_columns;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
|
|
51
|
+
// remove outer from inner
|
|
52
|
+
for (auto &corr_column : correlated_columns) {
|
|
53
|
+
auto entry = std::find(binder.correlated_columns.begin(), binder.correlated_columns.end(), corr_column);
|
|
54
|
+
if (entry != binder.correlated_columns.end()) {
|
|
55
|
+
binder.correlated_columns.erase(entry);
|
|
47
56
|
}
|
|
48
|
-
binder.correlated_columns.erase(entry);
|
|
49
57
|
}
|
|
58
|
+
|
|
59
|
+
// add inner to outer
|
|
60
|
+
for (auto &corr_column : binder.correlated_columns) {
|
|
61
|
+
correlated_columns.push_back(corr_column);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// clear inner
|
|
65
|
+
binder.correlated_columns.clear();
|
|
50
66
|
return all_correlated_columns;
|
|
51
67
|
}
|
|
52
68
|
|
|
@@ -57,6 +57,7 @@ void LogicalOperator::ResolveOperatorTypes() {
|
|
|
57
57
|
|
|
58
58
|
vector<ColumnBinding> LogicalOperator::GenerateColumnBindings(idx_t table_idx, idx_t column_count) {
|
|
59
59
|
vector<ColumnBinding> result;
|
|
60
|
+
result.reserve(column_count);
|
|
60
61
|
for (idx_t i = 0; i < column_count; i++) {
|
|
61
62
|
result.emplace_back(table_idx, i);
|
|
62
63
|
}
|
|
@@ -84,6 +85,7 @@ vector<ColumnBinding> LogicalOperator::MapBindings(const vector<ColumnBinding> &
|
|
|
84
85
|
vector<ColumnBinding> result_bindings;
|
|
85
86
|
result_bindings.reserve(projection_map.size());
|
|
86
87
|
for (auto index : projection_map) {
|
|
88
|
+
D_ASSERT(index < bindings.size());
|
|
87
89
|
result_bindings.push_back(bindings[index]);
|
|
88
90
|
}
|
|
89
91
|
return result_bindings;
|
|
@@ -338,6 +340,8 @@ unique_ptr<LogicalOperator> LogicalOperator::Deserialize(Deserializer &deseriali
|
|
|
338
340
|
case LogicalOperatorType::LOGICAL_DROP:
|
|
339
341
|
result = LogicalSimple::Deserialize(state, reader);
|
|
340
342
|
break;
|
|
343
|
+
case LogicalOperatorType::LOGICAL_DETACH:
|
|
344
|
+
throw SerializationException("Logical Detach does not support serialization");
|
|
341
345
|
case LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR:
|
|
342
346
|
result = LogicalExtensionOperator::Deserialize(state, reader);
|
|
343
347
|
break;
|
|
@@ -133,6 +133,7 @@ void Planner::CreatePlan(unique_ptr<SQLStatement> statement) {
|
|
|
133
133
|
case StatementType::EXECUTE_STATEMENT:
|
|
134
134
|
case StatementType::LOGICAL_PLAN_STATEMENT:
|
|
135
135
|
case StatementType::ATTACH_STATEMENT:
|
|
136
|
+
case StatementType::DETACH_STATEMENT:
|
|
136
137
|
CreatePlan(*statement);
|
|
137
138
|
break;
|
|
138
139
|
default:
|
|
@@ -447,8 +447,8 @@ public:
|
|
|
447
447
|
|
|
448
448
|
static void ReserveSpace(BitpackingCompressState<T> *state, idx_t data_bytes) {
|
|
449
449
|
idx_t meta_bytes = sizeof(bitpacking_metadata_encoded_t);
|
|
450
|
-
state->FlushAndCreateSegmentIfFull(data_bytes
|
|
451
|
-
D_ASSERT(data_bytes
|
|
450
|
+
state->FlushAndCreateSegmentIfFull(data_bytes, meta_bytes);
|
|
451
|
+
D_ASSERT(state->CanStore(data_bytes, meta_bytes));
|
|
452
452
|
}
|
|
453
453
|
|
|
454
454
|
static void UpdateStats(BitpackingCompressState<T> *state, idx_t count) {
|
|
@@ -461,9 +461,12 @@ public:
|
|
|
461
461
|
}
|
|
462
462
|
};
|
|
463
463
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
464
|
+
bool CanStore(idx_t data_bytes, idx_t meta_bytes) {
|
|
465
|
+
auto required_data_bytes = AlignValue<idx_t>((data_ptr + data_bytes) - data_ptr);
|
|
466
|
+
auto required_meta_bytes = Storage::BLOCK_SIZE - (metadata_ptr - data_ptr) + meta_bytes;
|
|
467
|
+
|
|
468
|
+
return required_data_bytes + required_meta_bytes <=
|
|
469
|
+
Storage::BLOCK_SIZE - BitpackingPrimitives::BITPACKING_HEADER_SIZE;
|
|
467
470
|
}
|
|
468
471
|
|
|
469
472
|
void CreateEmptySegment(idx_t row_start) {
|
|
@@ -489,8 +492,8 @@ public:
|
|
|
489
492
|
}
|
|
490
493
|
}
|
|
491
494
|
|
|
492
|
-
void FlushAndCreateSegmentIfFull(idx_t
|
|
493
|
-
if (
|
|
495
|
+
void FlushAndCreateSegmentIfFull(idx_t required_data_bytes, idx_t required_meta_bytes) {
|
|
496
|
+
if (!CanStore(required_data_bytes, required_meta_bytes)) {
|
|
494
497
|
auto row_start = current_segment->start + current_segment->count;
|
|
495
498
|
FlushSegment();
|
|
496
499
|
CreateEmptySegment(row_start);
|
|
@@ -505,6 +508,12 @@ public:
|
|
|
505
508
|
idx_t metadata_offset = AlignValue(data_ptr - base_ptr);
|
|
506
509
|
idx_t metadata_size = base_ptr + Storage::BLOCK_SIZE - metadata_ptr;
|
|
507
510
|
idx_t total_segment_size = metadata_offset + metadata_size;
|
|
511
|
+
|
|
512
|
+
// Asserting things are still sane here
|
|
513
|
+
if (!CanStore(0, 0)) {
|
|
514
|
+
throw InternalException("Error in bitpacking size calculation");
|
|
515
|
+
}
|
|
516
|
+
|
|
508
517
|
memmove(base_ptr + metadata_offset, metadata_ptr, metadata_size);
|
|
509
518
|
|
|
510
519
|
// Store the offset of the metadata of the first group (which is at the highest address).
|
|
@@ -1144,15 +1144,78 @@ void DataTable::UpdateColumn(TableCatalogEntry &table, ClientContext &context, V
|
|
|
1144
1144
|
}
|
|
1145
1145
|
|
|
1146
1146
|
//===--------------------------------------------------------------------===//
|
|
1147
|
-
//
|
|
1147
|
+
// Index Scan
|
|
1148
1148
|
//===--------------------------------------------------------------------===//
|
|
1149
|
-
void DataTable::
|
|
1149
|
+
void DataTable::InitializeWALCreateIndexScan(CreateIndexScanState &state, const vector<column_t> &column_ids) {
|
|
1150
1150
|
// we grab the append lock to make sure nothing is appended until AFTER we finish the index scan
|
|
1151
1151
|
state.append_lock = std::unique_lock<mutex>(append_lock);
|
|
1152
|
-
row_groups->InitializeCreateIndexScan(state);
|
|
1153
1152
|
InitializeScan(state, column_ids);
|
|
1154
1153
|
}
|
|
1155
1154
|
|
|
1155
|
+
void DataTable::WALAddIndex(ClientContext &context, unique_ptr<Index> index,
|
|
1156
|
+
const vector<unique_ptr<Expression>> &expressions) {
|
|
1157
|
+
|
|
1158
|
+
// if the data table is empty
|
|
1159
|
+
if (row_groups->IsEmpty()) {
|
|
1160
|
+
info->indexes.AddIndex(std::move(index));
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
auto &allocator = Allocator::Get(db);
|
|
1165
|
+
|
|
1166
|
+
DataChunk result;
|
|
1167
|
+
result.Initialize(allocator, index->logical_types);
|
|
1168
|
+
|
|
1169
|
+
DataChunk intermediate;
|
|
1170
|
+
vector<LogicalType> intermediate_types;
|
|
1171
|
+
auto column_ids = index->column_ids;
|
|
1172
|
+
column_ids.push_back(COLUMN_IDENTIFIER_ROW_ID);
|
|
1173
|
+
for (auto &id : index->column_ids) {
|
|
1174
|
+
auto &col = column_definitions[id];
|
|
1175
|
+
intermediate_types.push_back(col.Type());
|
|
1176
|
+
}
|
|
1177
|
+
intermediate_types.emplace_back(LogicalType::ROW_TYPE);
|
|
1178
|
+
intermediate.Initialize(allocator, intermediate_types);
|
|
1179
|
+
|
|
1180
|
+
// initialize an index scan
|
|
1181
|
+
CreateIndexScanState state;
|
|
1182
|
+
InitializeWALCreateIndexScan(state, column_ids);
|
|
1183
|
+
|
|
1184
|
+
if (!is_root) {
|
|
1185
|
+
throw InternalException("Error during WAL replay. Cannot add an index to a table that has been altered.");
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
// now start incrementally building the index
|
|
1189
|
+
{
|
|
1190
|
+
IndexLock lock;
|
|
1191
|
+
index->InitializeLock(lock);
|
|
1192
|
+
|
|
1193
|
+
while (true) {
|
|
1194
|
+
intermediate.Reset();
|
|
1195
|
+
result.Reset();
|
|
1196
|
+
// scan a new chunk from the table to index
|
|
1197
|
+
CreateIndexScan(state, intermediate, TableScanType::TABLE_SCAN_COMMITTED_ROWS_OMIT_PERMANENTLY_DELETED);
|
|
1198
|
+
if (intermediate.size() == 0) {
|
|
1199
|
+
// finished scanning for index creation
|
|
1200
|
+
// release all locks
|
|
1201
|
+
break;
|
|
1202
|
+
}
|
|
1203
|
+
// resolve the expressions for this chunk
|
|
1204
|
+
index->ExecuteExpressions(intermediate, result);
|
|
1205
|
+
|
|
1206
|
+
// insert into the index
|
|
1207
|
+
if (!index->Insert(lock, result, intermediate.data[intermediate.ColumnCount() - 1])) {
|
|
1208
|
+
throw InternalException("Error during WAL replay. Can't create unique index, table contains "
|
|
1209
|
+
"duplicate data on indexed column(s).");
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
info->indexes.AddIndex(std::move(index));
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
//===--------------------------------------------------------------------===//
|
|
1217
|
+
// Statistics
|
|
1218
|
+
//===--------------------------------------------------------------------===//
|
|
1156
1219
|
unique_ptr<BaseStatistics> DataTable::GetStatistics(ClientContext &context, column_t column_id) {
|
|
1157
1220
|
if (column_id == COLUMN_IDENTIFIER_ROW_ID) {
|
|
1158
1221
|
return nullptr;
|
|
@@ -86,7 +86,7 @@ bool Index::IndexIsUpdated(const vector<PhysicalIndex> &column_ids) const {
|
|
|
86
86
|
return false;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
BlockPointer Index::Serialize(
|
|
89
|
+
BlockPointer Index::Serialize(MetaBlockWriter &writer) {
|
|
90
90
|
throw NotImplementedException("The implementation of this index serialization does not exist.");
|
|
91
91
|
}
|
|
92
92
|
|
|
@@ -127,7 +127,7 @@ LocalTableStorage::LocalTableStorage(DataTable &table)
|
|
|
127
127
|
unbound_expressions.push_back(expr->Copy());
|
|
128
128
|
}
|
|
129
129
|
indexes.AddIndex(make_unique<ART>(art.column_ids, art.table_io_manager, std::move(unbound_expressions),
|
|
130
|
-
art.constraint_type, art.db,
|
|
130
|
+
art.constraint_type, art.db, true));
|
|
131
131
|
}
|
|
132
132
|
return false;
|
|
133
133
|
});
|
|
@@ -9,7 +9,8 @@ struct StorageVersionInfo {
|
|
|
9
9
|
idx_t storage_version;
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
static StorageVersionInfo storage_version_info[] = {{"v0.
|
|
12
|
+
static StorageVersionInfo storage_version_info[] = {{"v0.7.0", 43},
|
|
13
|
+
{"v0.6.0 or v0.6.1", 39},
|
|
13
14
|
{"v0.5.0 or v0.5.1", 38},
|
|
14
15
|
{"v0.3.3, v0.3.4 or v0.4.0", 33},
|
|
15
16
|
{"v0.3.2", 31},
|
|
@@ -27,8 +27,10 @@ ColumnData::ColumnData(BlockManager &block_manager, DataTableInfo &info, idx_t c
|
|
|
27
27
|
|
|
28
28
|
ColumnData::ColumnData(ColumnData &other, idx_t start, ColumnData *parent)
|
|
29
29
|
: block_manager(other.block_manager), info(other.info), column_index(other.column_index), start(start),
|
|
30
|
-
type(std::move(other.type)), parent(parent),
|
|
31
|
-
|
|
30
|
+
type(std::move(other.type)), parent(parent), version(parent ? parent->version + 1 : 0) {
|
|
31
|
+
if (other.updates) {
|
|
32
|
+
updates = make_unique<UpdateSegment>(*other.updates, *this);
|
|
33
|
+
}
|
|
32
34
|
idx_t offset = 0;
|
|
33
35
|
for (auto segment = other.data.GetRootSegment(); segment; segment = segment->Next()) {
|
|
34
36
|
auto &other = (ColumnSegment &)*segment;
|
|
@@ -36,6 +36,21 @@ UpdateSegment::UpdateSegment(ColumnData &column_data)
|
|
|
36
36
|
this->statistics_update_function = GetStatisticsUpdateFunction(physical_type);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
UpdateSegment::UpdateSegment(UpdateSegment &other, ColumnData &owner)
|
|
40
|
+
: column_data(owner), root(std::move(other.root)), stats(std::move(other.stats)), type_size(other.type_size) {
|
|
41
|
+
|
|
42
|
+
this->heap.Move(other.heap);
|
|
43
|
+
|
|
44
|
+
initialize_update_function = other.initialize_update_function;
|
|
45
|
+
merge_update_function = other.merge_update_function;
|
|
46
|
+
fetch_update_function = other.fetch_update_function;
|
|
47
|
+
fetch_committed_function = other.fetch_committed_function;
|
|
48
|
+
fetch_committed_range = other.fetch_committed_range;
|
|
49
|
+
fetch_row_function = other.fetch_row_function;
|
|
50
|
+
rollback_update_function = other.rollback_update_function;
|
|
51
|
+
statistics_update_function = other.statistics_update_function;
|
|
52
|
+
}
|
|
53
|
+
|
|
39
54
|
UpdateSegment::~UpdateSegment() {
|
|
40
55
|
}
|
|
41
56
|
|
|
@@ -60,8 +60,7 @@ void TableIndexList::VerifyForeignKey(const vector<PhysicalIndex> &fk_keys, Data
|
|
|
60
60
|
throw InternalException("Internal Foreign Key error: could not find index to verify...");
|
|
61
61
|
}
|
|
62
62
|
conflict_manager.SetIndexCount(1);
|
|
63
|
-
|
|
64
|
-
index->LookupValues(chunk, conflict_manager);
|
|
63
|
+
index->CheckConstraintsForChunk(chunk, conflict_manager);
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
vector<column_t> TableIndexList::GetRequiredColumns() {
|