duckdb 0.7.1-dev2.0 → 0.7.1-dev240.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 (104) 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/common/enums/logical_operator_type.cpp +2 -0
  16. package/src/duckdb/src/common/enums/physical_operator_type.cpp +2 -0
  17. package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
  18. package/src/duckdb/src/common/file_system.cpp +14 -0
  19. package/src/duckdb/src/common/hive_partitioning.cpp +1 -0
  20. package/src/duckdb/src/common/operator/cast_operators.cpp +14 -8
  21. package/src/duckdb/src/common/printer.cpp +1 -1
  22. package/src/duckdb/src/common/types/time.cpp +1 -1
  23. package/src/duckdb/src/common/types/timestamp.cpp +35 -4
  24. package/src/duckdb/src/common/types.cpp +36 -10
  25. package/src/duckdb/src/execution/column_binding_resolver.cpp +5 -2
  26. package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +7 -9
  27. package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +6 -11
  28. package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +13 -13
  29. package/src/duckdb/src/execution/operator/persistent/parallel_csv_reader.cpp +1 -1
  30. package/src/duckdb/src/execution/operator/schema/physical_detach.cpp +37 -0
  31. package/src/duckdb/src/execution/operator/schema/physical_drop.cpp +0 -5
  32. package/src/duckdb/src/execution/physical_plan/plan_simple.cpp +4 -0
  33. package/src/duckdb/src/execution/physical_plan_generator.cpp +1 -0
  34. package/src/duckdb/src/function/pragma/pragma_queries.cpp +36 -9
  35. package/src/duckdb/src/function/table/read_csv.cpp +15 -4
  36. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  37. package/src/duckdb/src/include/duckdb/common/enums/logical_operator_type.hpp +1 -0
  38. package/src/duckdb/src/include/duckdb/common/enums/physical_operator_type.hpp +1 -0
  39. package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +3 -2
  40. package/src/duckdb/src/include/duckdb/common/exception.hpp +10 -0
  41. package/src/duckdb/src/include/duckdb/common/file_system.hpp +1 -0
  42. package/src/duckdb/src/include/duckdb/common/hive_partitioning.hpp +9 -1
  43. package/src/duckdb/src/include/duckdb/common/radix_partitioning.hpp +4 -4
  44. package/src/duckdb/src/include/duckdb/common/types/timestamp.hpp +5 -1
  45. package/src/duckdb/src/include/duckdb/execution/operator/persistent/base_csv_reader.hpp +1 -3
  46. package/src/duckdb/src/include/duckdb/execution/operator/persistent/buffered_csv_reader.hpp +0 -2
  47. package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +2 -0
  48. package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_detach.hpp +32 -0
  49. package/src/duckdb/src/include/duckdb/main/client_data.hpp +2 -2
  50. package/src/duckdb/src/include/duckdb/main/config.hpp +0 -3
  51. package/src/duckdb/src/include/duckdb/parser/parsed_data/create_database_info.hpp +0 -4
  52. package/src/duckdb/src/include/duckdb/parser/parsed_data/detach_info.hpp +32 -0
  53. package/src/duckdb/src/include/duckdb/parser/query_node/select_node.hpp +1 -1
  54. package/src/duckdb/src/include/duckdb/parser/sql_statement.hpp +2 -2
  55. package/src/duckdb/src/include/duckdb/parser/statement/copy_statement.hpp +1 -1
  56. package/src/duckdb/src/include/duckdb/parser/statement/detach_statement.hpp +29 -0
  57. package/src/duckdb/src/include/duckdb/parser/statement/list.hpp +1 -0
  58. package/src/duckdb/src/include/duckdb/parser/statement/select_statement.hpp +3 -3
  59. package/src/duckdb/src/include/duckdb/parser/tableref/subqueryref.hpp +1 -1
  60. package/src/duckdb/src/include/duckdb/parser/tokens.hpp +1 -0
  61. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +1 -0
  62. package/src/duckdb/src/include/duckdb/planner/binder.hpp +1 -0
  63. package/src/duckdb/src/include/duckdb/planner/operator/logical_execute.hpp +1 -5
  64. package/src/duckdb/src/include/duckdb/planner/operator/logical_show.hpp +1 -2
  65. package/src/duckdb/src/include/duckdb/storage/storage_extension.hpp +7 -0
  66. package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -0
  67. package/src/duckdb/src/main/client_context.cpp +2 -0
  68. package/src/duckdb/src/main/extension/extension_alias.cpp +2 -1
  69. package/src/duckdb/src/optimizer/statistics/operator/propagate_join.cpp +2 -6
  70. package/src/duckdb/src/parser/statement/copy_statement.cpp +2 -13
  71. package/src/duckdb/src/parser/statement/delete_statement.cpp +3 -0
  72. package/src/duckdb/src/parser/statement/detach_statement.cpp +15 -0
  73. package/src/duckdb/src/parser/statement/insert_statement.cpp +9 -0
  74. package/src/duckdb/src/parser/statement/update_statement.cpp +3 -0
  75. package/src/duckdb/src/parser/transform/expression/transform_case.cpp +3 -3
  76. package/src/duckdb/src/parser/transform/statement/transform_create_database.cpp +0 -1
  77. package/src/duckdb/src/parser/transform/statement/transform_detach.cpp +19 -0
  78. package/src/duckdb/src/parser/transformer.cpp +2 -0
  79. package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +3 -0
  80. package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +6 -3
  81. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +16 -14
  82. package/src/duckdb/src/planner/binder/statement/bind_detach.cpp +19 -0
  83. package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +29 -4
  84. package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +22 -1
  85. package/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp +2 -1
  86. package/src/duckdb/src/planner/binder.cpp +2 -0
  87. package/src/duckdb/src/planner/expression_binder/lateral_binder.cpp +21 -5
  88. package/src/duckdb/src/planner/logical_operator.cpp +4 -0
  89. package/src/duckdb/src/planner/planner.cpp +1 -0
  90. package/src/duckdb/src/storage/storage_info.cpp +2 -1
  91. package/src/duckdb/src/storage/table/column_data.cpp +4 -2
  92. package/src/duckdb/src/storage/table/update_segment.cpp +15 -0
  93. package/src/duckdb/third_party/fmt/include/fmt/core.h +1 -2
  94. package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +1 -0
  95. package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +14 -0
  96. package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +530 -1006
  97. package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +17659 -17626
  98. package/src/duckdb/third_party/thrift/thrift/Thrift.h +8 -2
  99. package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
  100. package/src/duckdb/ub_src_execution_operator_schema.cpp +2 -0
  101. package/src/duckdb/ub_src_parser_statement.cpp +2 -0
  102. package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
  103. package/src/duckdb/ub_src_planner_binder_statement.cpp +2 -0
  104. package/src/duckdb/src/include/duckdb/function/create_database_extension.hpp +0 -37
@@ -0,0 +1,19 @@
1
+ #include "duckdb/parser/transformer.hpp"
2
+ #include "duckdb/parser/statement/detach_statement.hpp"
3
+ #include "duckdb/parser/expression/constant_expression.hpp"
4
+ #include "duckdb/common/string_util.hpp"
5
+
6
+ namespace duckdb {
7
+
8
+ unique_ptr<DetachStatement> Transformer::TransformDetach(duckdb_libpgquery::PGNode *node) {
9
+ auto stmt = reinterpret_cast<duckdb_libpgquery::PGDetachStmt *>(node);
10
+ auto result = make_unique<DetachStatement>();
11
+ auto info = make_unique<DetachInfo>();
12
+ info->name = stmt->db_name;
13
+ info->if_exists = stmt->missing_ok;
14
+
15
+ result->info = std::move(info);
16
+ return result;
17
+ }
18
+
19
+ } // namespace duckdb
@@ -145,6 +145,8 @@ unique_ptr<SQLStatement> Transformer::TransformStatementInternal(duckdb_libpgque
145
145
  return TransformAlterSequence(stmt);
146
146
  case duckdb_libpgquery::T_PGAttachStmt:
147
147
  return TransformAttach(stmt);
148
+ case duckdb_libpgquery::T_PGDetachStmt:
149
+ return TransformDetach(stmt);
148
150
  case duckdb_libpgquery::T_PGUseStmt:
149
151
  return TransformUse(stmt);
150
152
  case duckdb_libpgquery::T_PGCreateDatabaseStmt:
@@ -72,6 +72,9 @@ static void NegatePercentileFractions(ClientContext &context, unique_ptr<ParsedE
72
72
  for (const auto &element_val : ListValue::GetChildren(value)) {
73
73
  values.push_back(NegatePercentileValue(element_val, desc));
74
74
  }
75
+ if (values.empty()) {
76
+ throw BinderException("Empty list in percentile not allowed");
77
+ }
75
78
  bound.expr = make_unique<BoundConstantExpression>(Value::LIST(values));
76
79
  } else {
77
80
  bound.expr = make_unique<BoundConstantExpression>(NegatePercentileValue(value, desc));
@@ -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:
@@ -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));
@@ -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:
@@ -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
 
@@ -359,12 +359,11 @@ using wstring_view = basic_string_view<wchar_t>;
359
359
  #if FMT_HAS_FEATURE(__cpp_char8_t)
360
360
  typedef char8_t fmt_char8_t;
361
361
  #else
362
- typedef unsigned char fmt_char8_t;
362
+ typedef char fmt_char8_t;
363
363
  #endif
364
364
 
365
365
  /** Specifies if ``T`` is a character type. Can be specialized by users. */
366
366
  template <typename T> struct is_char : std::false_type {};
367
- template <> struct is_char<char> : std::true_type {};
368
367
  template <> struct is_char<wchar_t> : std::true_type {};
369
368
  template <> struct is_char<fmt_char8_t> : std::true_type {};
370
369
  template <> struct is_char<char16_t> : std::true_type {};
@@ -422,6 +422,7 @@ typedef enum PGNodeTag {
422
422
  T_PGExportStmt,
423
423
  T_PGImportStmt,
424
424
  T_PGAttachStmt,
425
+ T_PGDetachStmt,
425
426
  T_PGCreateDatabaseStmt,
426
427
  T_PGUseStmt,
427
428
 
@@ -2070,6 +2070,20 @@ typedef struct PGAttachStmt
2070
2070
  PGNode *query;
2071
2071
  } PGAttachStmt;
2072
2072
 
2073
+ /* ----------------------
2074
+ * Dettach Statement
2075
+ * ----------------------
2076
+ */
2077
+
2078
+ typedef struct PGDetachStmt
2079
+ {
2080
+ PGNodeTag type;
2081
+ char *db_name; /* list of names of attached databases */
2082
+ bool missing_ok;
2083
+ } PGDetachStmt;
2084
+
2085
+
2086
+
2073
2087
  /* ----------------------
2074
2088
  * CREATE DATABASE Statement
2075
2089
  * ----------------------