duckdb 0.7.1-dev37.0 → 0.7.1-dev415.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 (171) hide show
  1. package/README.md +1 -1
  2. package/binding.gyp +7 -7
  3. package/package.json +3 -3
  4. package/src/duckdb/extension/json/buffered_json_reader.cpp +50 -9
  5. package/src/duckdb/extension/json/include/buffered_json_reader.hpp +7 -2
  6. package/src/duckdb/extension/json/include/json_scan.hpp +45 -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_structure.cpp +8 -3
  10. package/src/duckdb/extension/json/json_functions/json_transform.cpp +54 -10
  11. package/src/duckdb/extension/json/json_functions/read_json.cpp +104 -49
  12. package/src/duckdb/extension/json/json_functions/read_json_objects.cpp +5 -3
  13. package/src/duckdb/extension/json/json_functions.cpp +7 -0
  14. package/src/duckdb/extension/json/json_scan.cpp +144 -37
  15. package/src/duckdb/extension/parquet/column_reader.cpp +7 -0
  16. package/src/duckdb/extension/parquet/include/column_reader.hpp +1 -0
  17. package/src/duckdb/extension/parquet/parquet-extension.cpp +2 -9
  18. package/src/duckdb/src/catalog/catalog.cpp +62 -13
  19. package/src/duckdb/src/catalog/catalog_entry/index_catalog_entry.cpp +8 -7
  20. package/src/duckdb/src/catalog/catalog_entry/schema_catalog_entry.cpp +1 -1
  21. package/src/duckdb/src/catalog/catalog_set.cpp +1 -1
  22. package/src/duckdb/src/catalog/default/default_views.cpp +1 -1
  23. package/src/duckdb/src/common/bind_helpers.cpp +55 -0
  24. package/src/duckdb/src/common/enums/logical_operator_type.cpp +2 -0
  25. package/src/duckdb/src/common/enums/physical_operator_type.cpp +2 -0
  26. package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
  27. package/src/duckdb/src/common/file_system.cpp +28 -0
  28. package/src/duckdb/src/common/hive_partitioning.cpp +1 -0
  29. package/src/duckdb/src/common/local_file_system.cpp +4 -4
  30. package/src/duckdb/src/common/operator/cast_operators.cpp +10 -4
  31. package/src/duckdb/src/common/string_util.cpp +8 -4
  32. package/src/duckdb/src/common/types/partitioned_column_data.cpp +1 -0
  33. package/src/duckdb/src/common/types/time.cpp +1 -1
  34. package/src/duckdb/src/common/types/timestamp.cpp +35 -4
  35. package/src/duckdb/src/common/types.cpp +37 -11
  36. package/src/duckdb/src/execution/column_binding_resolver.cpp +5 -2
  37. package/src/duckdb/src/execution/index/art/art.cpp +117 -67
  38. package/src/duckdb/src/execution/index/art/art_key.cpp +24 -12
  39. package/src/duckdb/src/execution/index/art/leaf.cpp +7 -8
  40. package/src/duckdb/src/execution/index/art/node.cpp +13 -27
  41. package/src/duckdb/src/execution/index/art/node16.cpp +5 -8
  42. package/src/duckdb/src/execution/index/art/node256.cpp +3 -5
  43. package/src/duckdb/src/execution/index/art/node4.cpp +4 -7
  44. package/src/duckdb/src/execution/index/art/node48.cpp +5 -8
  45. package/src/duckdb/src/execution/index/art/prefix.cpp +2 -3
  46. package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +6 -27
  47. package/src/duckdb/src/execution/operator/helper/physical_reset.cpp +1 -9
  48. package/src/duckdb/src/execution/operator/helper/physical_set.cpp +1 -9
  49. package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +7 -9
  50. package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +6 -11
  51. package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +13 -13
  52. package/src/duckdb/src/execution/operator/schema/physical_detach.cpp +37 -0
  53. package/src/duckdb/src/execution/operator/schema/physical_drop.cpp +0 -5
  54. package/src/duckdb/src/execution/physical_operator.cpp +6 -6
  55. package/src/duckdb/src/execution/physical_plan/plan_simple.cpp +4 -0
  56. package/src/duckdb/src/execution/physical_plan_generator.cpp +1 -0
  57. package/src/duckdb/src/function/pragma/pragma_queries.cpp +38 -11
  58. package/src/duckdb/src/function/scalar/generic/current_setting.cpp +2 -2
  59. package/src/duckdb/src/function/scalar/map/map.cpp +69 -21
  60. package/src/duckdb/src/function/table/read_csv.cpp +17 -5
  61. package/src/duckdb/src/function/table/system/duckdb_temporary_files.cpp +59 -0
  62. package/src/duckdb/src/function/table/system_functions.cpp +1 -0
  63. package/src/duckdb/src/function/table/table_scan.cpp +3 -0
  64. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  65. package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +7 -1
  66. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_index_entry.hpp +1 -1
  67. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/index_catalog_entry.hpp +1 -1
  68. package/src/duckdb/src/include/duckdb/common/bind_helpers.hpp +2 -0
  69. package/src/duckdb/src/include/duckdb/common/enums/logical_operator_type.hpp +1 -0
  70. package/src/duckdb/src/include/duckdb/common/enums/physical_operator_type.hpp +1 -0
  71. package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +3 -2
  72. package/src/duckdb/src/include/duckdb/common/enums/wal_type.hpp +3 -0
  73. package/src/duckdb/src/include/duckdb/common/exception.hpp +10 -0
  74. package/src/duckdb/src/include/duckdb/common/file_system.hpp +1 -0
  75. package/src/duckdb/src/include/duckdb/common/hive_partitioning.hpp +9 -1
  76. package/src/duckdb/src/include/duckdb/common/radix_partitioning.hpp +4 -4
  77. package/src/duckdb/src/include/duckdb/common/string_util.hpp +9 -2
  78. package/src/duckdb/src/include/duckdb/common/types/timestamp.hpp +5 -1
  79. package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +37 -41
  80. package/src/duckdb/src/include/duckdb/execution/index/art/art_key.hpp +8 -11
  81. package/src/duckdb/src/include/duckdb/execution/operator/persistent/base_csv_reader.hpp +1 -3
  82. package/src/duckdb/src/include/duckdb/execution/operator/persistent/buffered_csv_reader.hpp +0 -2
  83. package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +2 -0
  84. package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_detach.hpp +32 -0
  85. package/src/duckdb/src/include/duckdb/function/table/system_functions.hpp +4 -0
  86. package/src/duckdb/src/include/duckdb/main/client_data.hpp +2 -2
  87. package/src/duckdb/src/include/duckdb/main/config.hpp +2 -3
  88. package/src/duckdb/src/include/duckdb/main/{extension_functions.hpp → extension_entries.hpp} +26 -5
  89. package/src/duckdb/src/include/duckdb/main/extension_helper.hpp +3 -0
  90. package/src/duckdb/src/include/duckdb/main/settings.hpp +9 -0
  91. package/src/duckdb/src/include/duckdb/parallel/pipeline_executor.hpp +0 -7
  92. package/src/duckdb/src/include/duckdb/parser/parsed_data/create_database_info.hpp +0 -4
  93. package/src/duckdb/src/include/duckdb/parser/parsed_data/detach_info.hpp +32 -0
  94. package/src/duckdb/src/include/duckdb/parser/query_node/select_node.hpp +1 -1
  95. package/src/duckdb/src/include/duckdb/parser/sql_statement.hpp +2 -2
  96. package/src/duckdb/src/include/duckdb/parser/statement/copy_statement.hpp +1 -1
  97. package/src/duckdb/src/include/duckdb/parser/statement/detach_statement.hpp +29 -0
  98. package/src/duckdb/src/include/duckdb/parser/statement/list.hpp +1 -0
  99. package/src/duckdb/src/include/duckdb/parser/statement/select_statement.hpp +3 -3
  100. package/src/duckdb/src/include/duckdb/parser/tableref/subqueryref.hpp +1 -1
  101. package/src/duckdb/src/include/duckdb/parser/tokens.hpp +1 -0
  102. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +1 -0
  103. package/src/duckdb/src/include/duckdb/planner/binder.hpp +4 -0
  104. package/src/duckdb/src/include/duckdb/planner/expression_binder/index_binder.hpp +10 -3
  105. package/src/duckdb/src/include/duckdb/planner/operator/logical_execute.hpp +1 -5
  106. package/src/duckdb/src/include/duckdb/planner/operator/logical_show.hpp +1 -2
  107. package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +8 -0
  108. package/src/duckdb/src/include/duckdb/storage/data_table.hpp +7 -1
  109. package/src/duckdb/src/include/duckdb/storage/index.hpp +47 -38
  110. package/src/duckdb/src/include/duckdb/storage/storage_extension.hpp +7 -0
  111. package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -0
  112. package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +7 -0
  113. package/src/duckdb/src/main/client_context.cpp +2 -0
  114. package/src/duckdb/src/main/config.cpp +1 -0
  115. package/src/duckdb/src/main/database.cpp +14 -5
  116. package/src/duckdb/src/main/extension/extension_alias.cpp +2 -1
  117. package/src/duckdb/src/main/extension/extension_install.cpp +43 -9
  118. package/src/duckdb/src/main/extension/extension_load.cpp +29 -5
  119. package/src/duckdb/src/main/settings/settings.cpp +16 -0
  120. package/src/duckdb/src/optimizer/statistics/operator/propagate_join.cpp +2 -6
  121. package/src/duckdb/src/parallel/pipeline_executor.cpp +1 -55
  122. package/src/duckdb/src/parser/parsed_data/create_index_info.cpp +3 -0
  123. package/src/duckdb/src/parser/statement/copy_statement.cpp +2 -13
  124. package/src/duckdb/src/parser/statement/delete_statement.cpp +3 -0
  125. package/src/duckdb/src/parser/statement/detach_statement.cpp +15 -0
  126. package/src/duckdb/src/parser/statement/insert_statement.cpp +9 -0
  127. package/src/duckdb/src/parser/statement/update_statement.cpp +3 -0
  128. package/src/duckdb/src/parser/transform/expression/transform_case.cpp +3 -3
  129. package/src/duckdb/src/parser/transform/statement/transform_create_database.cpp +0 -1
  130. package/src/duckdb/src/parser/transform/statement/transform_detach.cpp +19 -0
  131. package/src/duckdb/src/parser/transformer.cpp +2 -0
  132. package/src/duckdb/src/planner/bind_context.cpp +1 -1
  133. package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +3 -0
  134. package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +7 -14
  135. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +16 -14
  136. package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +13 -0
  137. package/src/duckdb/src/planner/binder/statement/bind_detach.cpp +19 -0
  138. package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +29 -4
  139. package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +22 -1
  140. package/src/duckdb/src/planner/binder.cpp +2 -0
  141. package/src/duckdb/src/planner/expression_binder/index_binder.cpp +32 -1
  142. package/src/duckdb/src/planner/logical_operator.cpp +6 -1
  143. package/src/duckdb/src/planner/planner.cpp +1 -0
  144. package/src/duckdb/src/storage/buffer_manager.cpp +105 -26
  145. package/src/duckdb/src/storage/compression/bitpacking.cpp +16 -7
  146. package/src/duckdb/src/storage/data_table.cpp +66 -3
  147. package/src/duckdb/src/storage/index.cpp +1 -1
  148. package/src/duckdb/src/storage/local_storage.cpp +1 -1
  149. package/src/duckdb/src/storage/table/column_data.cpp +4 -2
  150. package/src/duckdb/src/storage/table/update_segment.cpp +15 -0
  151. package/src/duckdb/src/storage/table_index_list.cpp +1 -2
  152. package/src/duckdb/src/storage/wal_replay.cpp +68 -0
  153. package/src/duckdb/src/storage/write_ahead_log.cpp +21 -1
  154. package/src/duckdb/src/transaction/commit_state.cpp +5 -2
  155. package/src/duckdb/third_party/concurrentqueue/blockingconcurrentqueue.h +2 -2
  156. package/src/duckdb/third_party/fmt/include/fmt/core.h +1 -2
  157. package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +1 -0
  158. package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +14 -0
  159. package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +530 -1006
  160. package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +17659 -17626
  161. package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
  162. package/src/duckdb/ub_src_execution_operator_schema.cpp +2 -0
  163. package/src/duckdb/ub_src_function_table_system.cpp +2 -0
  164. package/src/duckdb/ub_src_parser_statement.cpp +2 -0
  165. package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
  166. package/src/duckdb/ub_src_planner_binder_statement.cpp +2 -0
  167. package/src/statement.cpp +46 -12
  168. package/test/arrow.test.ts +3 -3
  169. package/test/prepare.test.ts +39 -1
  170. package/test/typescript_decls.test.ts +1 -1
  171. package/src/duckdb/src/include/duckdb/function/create_database_extension.hpp +0 -37
@@ -13,6 +13,9 @@ DeleteStatement::DeleteStatement(const DeleteStatement &other) : SQLStatement(ot
13
13
  for (const auto &using_clause : other.using_clauses) {
14
14
  using_clauses.push_back(using_clause->Copy());
15
15
  }
16
+ for (auto &expr : other.returning_list) {
17
+ returning_list.emplace_back(expr->Copy());
18
+ }
16
19
  cte_map = other.cte_map.Copy();
17
20
  }
18
21
 
@@ -0,0 +1,15 @@
1
+ #include "duckdb/parser/statement/detach_statement.hpp"
2
+
3
+ namespace duckdb {
4
+
5
+ DetachStatement::DetachStatement() : SQLStatement(StatementType::DETACH_STATEMENT) {
6
+ }
7
+
8
+ DetachStatement::DetachStatement(const DetachStatement &other) : SQLStatement(other), info(other.info->Copy()) {
9
+ }
10
+
11
+ unique_ptr<SQLStatement> DetachStatement::Copy() const {
12
+ return unique_ptr<DetachStatement>(new DetachStatement(*this));
13
+ }
14
+
15
+ } // namespace duckdb
@@ -13,6 +13,9 @@ OnConflictInfo::OnConflictInfo(const OnConflictInfo &other)
13
13
  if (other.set_info) {
14
14
  set_info = other.set_info->Copy();
15
15
  }
16
+ if (other.condition) {
17
+ condition = other.condition->Copy();
18
+ }
16
19
  }
17
20
 
18
21
  unique_ptr<OnConflictInfo> OnConflictInfo::Copy() const {
@@ -28,6 +31,12 @@ InsertStatement::InsertStatement(const InsertStatement &other)
28
31
  select_statement(unique_ptr_cast<SQLStatement, SelectStatement>(other.select_statement->Copy())),
29
32
  columns(other.columns), table(other.table), schema(other.schema), catalog(other.catalog) {
30
33
  cte_map = other.cte_map.Copy();
34
+ for (auto &expr : other.returning_list) {
35
+ returning_list.emplace_back(expr->Copy());
36
+ }
37
+ if (other.table_ref) {
38
+ table_ref = other.table_ref->Copy();
39
+ }
31
40
  if (other.on_conflict_info) {
32
41
  on_conflict_info = other.on_conflict_info->Copy();
33
42
  }
@@ -27,6 +27,9 @@ UpdateStatement::UpdateStatement(const UpdateStatement &other)
27
27
  if (other.from_table) {
28
28
  from_table = other.from_table->Copy();
29
29
  }
30
+ for (auto &expr : other.returning_list) {
31
+ returning_list.emplace_back(expr->Copy());
32
+ }
30
33
  cte_map = other.cte_map.Copy();
31
34
  }
32
35
 
@@ -9,16 +9,16 @@ unique_ptr<ParsedExpression> Transformer::TransformCase(duckdb_libpgquery::PGCas
9
9
  D_ASSERT(root);
10
10
 
11
11
  auto case_node = make_unique<CaseExpression>();
12
+ auto root_arg = TransformExpression(reinterpret_cast<duckdb_libpgquery::PGNode *>(root->arg));
12
13
  for (auto cell = root->args->head; cell != nullptr; cell = cell->next) {
13
14
  CaseCheck case_check;
14
15
 
15
16
  auto w = reinterpret_cast<duckdb_libpgquery::PGCaseWhen *>(cell->data.ptr_value);
16
17
  auto test_raw = TransformExpression(reinterpret_cast<duckdb_libpgquery::PGNode *>(w->expr));
17
18
  unique_ptr<ParsedExpression> test;
18
- auto arg = TransformExpression(reinterpret_cast<duckdb_libpgquery::PGNode *>(root->arg));
19
- if (arg) {
19
+ if (root_arg) {
20
20
  case_check.when_expr =
21
- make_unique<ComparisonExpression>(ExpressionType::COMPARE_EQUAL, std::move(arg), std::move(test_raw));
21
+ make_unique<ComparisonExpression>(ExpressionType::COMPARE_EQUAL, root_arg->Copy(), std::move(test_raw));
22
22
  } else {
23
23
  case_check.when_expr = std::move(test_raw);
24
24
  }
@@ -11,7 +11,6 @@ unique_ptr<CreateStatement> Transformer::TransformCreateDatabase(duckdb_libpgque
11
11
  auto result = make_unique<CreateStatement>();
12
12
  auto info = make_unique<CreateDatabaseInfo>();
13
13
 
14
- info->extension_name = stmt->extension ? stmt->extension : string();
15
14
  info->path = stmt->path ? stmt->path : string();
16
15
 
17
16
  auto qualified_name = TransformQualifiedName(stmt->name);
@@ -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:
@@ -44,7 +44,7 @@ vector<string> BindContext::GetSimilarBindings(const string &column_name) {
44
44
  for (auto &kv : bindings) {
45
45
  auto binding = kv.second.get();
46
46
  for (auto &name : binding->names) {
47
- idx_t distance = StringUtil::LevenshteinDistance(name, column_name);
47
+ idx_t distance = StringUtil::SimilarityScore(name, column_name);
48
48
  scores.emplace_back(binding->alias + "." + name, distance);
49
49
  }
50
50
  }
@@ -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));
@@ -23,16 +23,6 @@
23
23
 
24
24
  namespace duckdb {
25
25
 
26
- static vector<idx_t> ColumnListToIndices(const vector<bool> &vec) {
27
- vector<idx_t> ret;
28
- for (idx_t i = 0; i < vec.size(); i++) {
29
- if (vec[i]) {
30
- ret.push_back(i);
31
- }
32
- }
33
- return ret;
34
- }
35
-
36
26
  vector<string> GetUniqueNames(const vector<string> &original_names) {
37
27
  unordered_set<string> name_set;
38
28
  vector<string> unique_names;
@@ -97,22 +87,25 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt) {
97
87
  for (auto &option : original_options) {
98
88
  auto loption = StringUtil::Lower(option.first);
99
89
  if (loption == "use_tmp_file") {
100
- use_tmp_file = option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue<bool>();
90
+ use_tmp_file =
91
+ option.second.empty() || option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue<bool>();
101
92
  user_set_use_tmp_file = true;
102
93
  continue;
103
94
  }
104
95
  if (loption == "allow_overwrite") {
105
- allow_overwrite = option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue<bool>();
96
+ allow_overwrite =
97
+ option.second.empty() || option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue<bool>();
106
98
  continue;
107
99
  }
108
100
 
109
101
  if (loption == "per_thread_output") {
110
- per_thread_output = option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue<bool>();
102
+ per_thread_output =
103
+ option.second.empty() || option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue<bool>();
111
104
  continue;
112
105
  }
113
106
  if (loption == "partition_by") {
114
107
  auto converted = ConvertVectorToValue(std::move(option.second));
115
- partition_cols = ColumnListToIndices(ParseColumnList(converted, select_node.names, loption));
108
+ partition_cols = ParseColumnsOrdered(converted, select_node.names, loption);
116
109
  continue;
117
110
  }
118
111
  stmt.info->options[option.first] = option.second;
@@ -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::BIGINT};
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);
@@ -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
  }
@@ -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;
@@ -165,7 +167,8 @@ idx_t LogicalOperator::EstimateCardinality(ClientContext &context) {
165
167
  max_cardinality = MaxValue(child->EstimateCardinality(context), max_cardinality);
166
168
  }
167
169
  has_estimated_cardinality = true;
168
- return max_cardinality;
170
+ estimated_cardinality = max_cardinality;
171
+ return estimated_cardinality;
169
172
  }
170
173
 
171
174
  void LogicalOperator::Print() {
@@ -338,6 +341,8 @@ unique_ptr<LogicalOperator> LogicalOperator::Deserialize(Deserializer &deseriali
338
341
  case LogicalOperatorType::LOGICAL_DROP:
339
342
  result = LogicalSimple::Deserialize(state, reader);
340
343
  break;
344
+ case LogicalOperatorType::LOGICAL_DETACH:
345
+ throw SerializationException("Logical Detach does not support serialization");
341
346
  case LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR:
342
347
  result = LogicalExtensionOperator::Deserialize(state, reader);
343
348
  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: