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.
Files changed (140) hide show
  1. package/binding.gyp +7 -7
  2. package/package.json +1 -1
  3. package/src/duckdb/extension/json/buffered_json_reader.cpp +50 -9
  4. package/src/duckdb/extension/json/include/buffered_json_reader.hpp +7 -2
  5. package/src/duckdb/extension/json/include/json_common.hpp +2 -2
  6. package/src/duckdb/extension/json/include/json_scan.hpp +29 -10
  7. package/src/duckdb/extension/json/json_functions/copy_json.cpp +35 -22
  8. package/src/duckdb/extension/json/json_functions/json_create.cpp +8 -8
  9. package/src/duckdb/extension/json/json_functions/json_transform.cpp +47 -8
  10. package/src/duckdb/extension/json/json_functions/read_json.cpp +104 -49
  11. package/src/duckdb/extension/json/json_functions/read_json_objects.cpp +5 -3
  12. package/src/duckdb/extension/json/json_functions.cpp +6 -0
  13. package/src/duckdb/extension/json/json_scan.cpp +144 -34
  14. package/src/duckdb/extension/parquet/parquet-extension.cpp +3 -2
  15. package/src/duckdb/src/catalog/catalog.cpp +15 -0
  16. package/src/duckdb/src/catalog/catalog_entry/index_catalog_entry.cpp +8 -7
  17. package/src/duckdb/src/common/enums/logical_operator_type.cpp +2 -0
  18. package/src/duckdb/src/common/enums/physical_operator_type.cpp +2 -0
  19. package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
  20. package/src/duckdb/src/common/file_system.cpp +14 -0
  21. package/src/duckdb/src/common/hive_partitioning.cpp +1 -0
  22. package/src/duckdb/src/common/operator/cast_operators.cpp +14 -8
  23. package/src/duckdb/src/common/printer.cpp +1 -1
  24. package/src/duckdb/src/common/types/time.cpp +1 -1
  25. package/src/duckdb/src/common/types/timestamp.cpp +35 -4
  26. package/src/duckdb/src/common/types.cpp +36 -10
  27. package/src/duckdb/src/execution/column_binding_resolver.cpp +5 -2
  28. package/src/duckdb/src/execution/index/art/art.cpp +117 -67
  29. package/src/duckdb/src/execution/index/art/art_key.cpp +24 -12
  30. package/src/duckdb/src/execution/index/art/leaf.cpp +7 -8
  31. package/src/duckdb/src/execution/index/art/node.cpp +13 -27
  32. package/src/duckdb/src/execution/index/art/node16.cpp +5 -8
  33. package/src/duckdb/src/execution/index/art/node256.cpp +3 -5
  34. package/src/duckdb/src/execution/index/art/node4.cpp +4 -7
  35. package/src/duckdb/src/execution/index/art/node48.cpp +5 -8
  36. package/src/duckdb/src/execution/index/art/prefix.cpp +2 -3
  37. package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +7 -9
  38. package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +6 -11
  39. package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +13 -13
  40. package/src/duckdb/src/execution/operator/persistent/parallel_csv_reader.cpp +1 -1
  41. package/src/duckdb/src/execution/operator/schema/physical_detach.cpp +37 -0
  42. package/src/duckdb/src/execution/operator/schema/physical_drop.cpp +0 -5
  43. package/src/duckdb/src/execution/physical_plan/plan_simple.cpp +4 -0
  44. package/src/duckdb/src/execution/physical_plan_generator.cpp +1 -0
  45. package/src/duckdb/src/function/pragma/pragma_queries.cpp +38 -11
  46. package/src/duckdb/src/function/table/read_csv.cpp +17 -5
  47. package/src/duckdb/src/function/table/table_scan.cpp +3 -0
  48. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  49. package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +5 -1
  50. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_index_entry.hpp +1 -1
  51. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/index_catalog_entry.hpp +1 -1
  52. package/src/duckdb/src/include/duckdb/common/enums/logical_operator_type.hpp +1 -0
  53. package/src/duckdb/src/include/duckdb/common/enums/physical_operator_type.hpp +1 -0
  54. package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +3 -2
  55. package/src/duckdb/src/include/duckdb/common/enums/wal_type.hpp +3 -0
  56. package/src/duckdb/src/include/duckdb/common/exception.hpp +10 -0
  57. package/src/duckdb/src/include/duckdb/common/file_system.hpp +1 -0
  58. package/src/duckdb/src/include/duckdb/common/hive_partitioning.hpp +9 -1
  59. package/src/duckdb/src/include/duckdb/common/radix_partitioning.hpp +4 -4
  60. package/src/duckdb/src/include/duckdb/common/types/timestamp.hpp +5 -1
  61. package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +37 -41
  62. package/src/duckdb/src/include/duckdb/execution/index/art/art_key.hpp +8 -11
  63. package/src/duckdb/src/include/duckdb/execution/operator/persistent/base_csv_reader.hpp +1 -3
  64. package/src/duckdb/src/include/duckdb/execution/operator/persistent/buffered_csv_reader.hpp +0 -2
  65. package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +2 -0
  66. package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_detach.hpp +32 -0
  67. package/src/duckdb/src/include/duckdb/main/client_data.hpp +2 -2
  68. package/src/duckdb/src/include/duckdb/main/config.hpp +0 -3
  69. package/src/duckdb/src/include/duckdb/parser/parsed_data/create_database_info.hpp +0 -4
  70. package/src/duckdb/src/include/duckdb/parser/parsed_data/detach_info.hpp +32 -0
  71. package/src/duckdb/src/include/duckdb/parser/query_node/select_node.hpp +1 -1
  72. package/src/duckdb/src/include/duckdb/parser/sql_statement.hpp +2 -2
  73. package/src/duckdb/src/include/duckdb/parser/statement/copy_statement.hpp +1 -1
  74. package/src/duckdb/src/include/duckdb/parser/statement/detach_statement.hpp +29 -0
  75. package/src/duckdb/src/include/duckdb/parser/statement/list.hpp +1 -0
  76. package/src/duckdb/src/include/duckdb/parser/statement/select_statement.hpp +3 -3
  77. package/src/duckdb/src/include/duckdb/parser/tableref/subqueryref.hpp +1 -1
  78. package/src/duckdb/src/include/duckdb/parser/tokens.hpp +1 -0
  79. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +1 -0
  80. package/src/duckdb/src/include/duckdb/planner/binder.hpp +4 -0
  81. package/src/duckdb/src/include/duckdb/planner/expression_binder/index_binder.hpp +10 -3
  82. package/src/duckdb/src/include/duckdb/planner/operator/logical_execute.hpp +1 -5
  83. package/src/duckdb/src/include/duckdb/planner/operator/logical_show.hpp +1 -2
  84. package/src/duckdb/src/include/duckdb/storage/data_table.hpp +7 -1
  85. package/src/duckdb/src/include/duckdb/storage/index.hpp +47 -38
  86. package/src/duckdb/src/include/duckdb/storage/storage_extension.hpp +7 -0
  87. package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -0
  88. package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +7 -0
  89. package/src/duckdb/src/main/client_context.cpp +2 -0
  90. package/src/duckdb/src/main/extension/extension_alias.cpp +2 -1
  91. package/src/duckdb/src/optimizer/statistics/operator/propagate_join.cpp +2 -6
  92. package/src/duckdb/src/parser/parsed_data/create_index_info.cpp +3 -0
  93. package/src/duckdb/src/parser/statement/copy_statement.cpp +2 -13
  94. package/src/duckdb/src/parser/statement/delete_statement.cpp +3 -0
  95. package/src/duckdb/src/parser/statement/detach_statement.cpp +15 -0
  96. package/src/duckdb/src/parser/statement/insert_statement.cpp +9 -0
  97. package/src/duckdb/src/parser/statement/update_statement.cpp +3 -0
  98. package/src/duckdb/src/parser/transform/expression/transform_case.cpp +3 -3
  99. package/src/duckdb/src/parser/transform/statement/transform_create_database.cpp +0 -1
  100. package/src/duckdb/src/parser/transform/statement/transform_detach.cpp +19 -0
  101. package/src/duckdb/src/parser/transformer.cpp +2 -0
  102. package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +3 -0
  103. package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +6 -3
  104. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +16 -14
  105. package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +13 -0
  106. package/src/duckdb/src/planner/binder/statement/bind_detach.cpp +19 -0
  107. package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +29 -4
  108. package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +22 -1
  109. package/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp +2 -1
  110. package/src/duckdb/src/planner/binder.cpp +2 -0
  111. package/src/duckdb/src/planner/expression_binder/index_binder.cpp +32 -1
  112. package/src/duckdb/src/planner/expression_binder/lateral_binder.cpp +21 -5
  113. package/src/duckdb/src/planner/logical_operator.cpp +4 -0
  114. package/src/duckdb/src/planner/planner.cpp +1 -0
  115. package/src/duckdb/src/storage/compression/bitpacking.cpp +16 -7
  116. package/src/duckdb/src/storage/data_table.cpp +66 -3
  117. package/src/duckdb/src/storage/index.cpp +1 -1
  118. package/src/duckdb/src/storage/local_storage.cpp +1 -1
  119. package/src/duckdb/src/storage/storage_info.cpp +2 -1
  120. package/src/duckdb/src/storage/table/column_data.cpp +4 -2
  121. package/src/duckdb/src/storage/table/update_segment.cpp +15 -0
  122. package/src/duckdb/src/storage/table_index_list.cpp +1 -2
  123. package/src/duckdb/src/storage/wal_replay.cpp +68 -0
  124. package/src/duckdb/src/storage/write_ahead_log.cpp +21 -1
  125. package/src/duckdb/src/transaction/commit_state.cpp +5 -2
  126. package/src/duckdb/third_party/fmt/include/fmt/core.h +1 -2
  127. package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +1 -0
  128. package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +14 -0
  129. package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +530 -1006
  130. package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +17659 -17626
  131. package/src/duckdb/third_party/thrift/thrift/Thrift.h +8 -2
  132. package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
  133. package/src/duckdb/ub_src_execution_operator_schema.cpp +2 -0
  134. package/src/duckdb/ub_src_parser_statement.cpp +2 -0
  135. package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
  136. package/src/duckdb/ub_src_planner_binder_statement.cpp +2 -0
  137. package/src/statement.cpp +46 -12
  138. package/test/prepare.test.ts +39 -1
  139. package/test/typescript_decls.test.ts +1 -1
  140. 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 = option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue<bool>();
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 = option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue<bool>();
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 = option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue<bool>();
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
- for (auto &extension : config.create_database_extensions) {
660
- auto create_database_function_ref =
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
- // attaching and detaching is read-only
48
- stmt.info->catalog = SYSTEM_CATALOG;
49
- break;
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 projection_index = insert.children[0]->GetTableIndex()[0];
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 &current_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 = &current_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) : ExpressionBinder(binder, 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
- for (auto &correlated : correlated_columns) {
44
- auto entry = std::find(binder.correlated_columns.begin(), binder.correlated_columns.end(), correlated);
45
- if (entry == binder.correlated_columns.end()) {
46
- throw InternalException("Lateral Binder: could not find correlated column in binder");
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 + meta_bytes);
451
- D_ASSERT(data_bytes + meta_bytes <= state->RemainingSize());
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
- // Space remaining between the metadata_ptr growing down and data ptr growing up
465
- idx_t RemainingSize() {
466
- return metadata_ptr - data_ptr;
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 required_space) {
493
- if (RemainingSize() < required_space) {
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
- // Create Index Scan
1147
+ // Index Scan
1148
1148
  //===--------------------------------------------------------------------===//
1149
- void DataTable::InitializeCreateIndexScan(CreateIndexScanState &state, const vector<column_t> &column_ids) {
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(duckdb::MetaBlockWriter &writer) {
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, false));
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.6.0 or v0.6.1", 39},
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), updates(std::move(other.updates)),
31
- version(parent ? parent->version + 1 : 0) {
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() {