duckdb 0.7.1-dev7.0 → 0.7.1

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 (182) 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_functions.cpp +1 -0
  23. package/src/duckdb/src/catalog/default/default_views.cpp +1 -1
  24. package/src/duckdb/src/common/bind_helpers.cpp +55 -0
  25. package/src/duckdb/src/common/enums/logical_operator_type.cpp +2 -0
  26. package/src/duckdb/src/common/enums/physical_operator_type.cpp +2 -0
  27. package/src/duckdb/src/common/enums/statement_type.cpp +2 -0
  28. package/src/duckdb/src/common/file_system.cpp +28 -0
  29. package/src/duckdb/src/common/hive_partitioning.cpp +1 -0
  30. package/src/duckdb/src/common/local_file_system.cpp +4 -4
  31. package/src/duckdb/src/common/operator/cast_operators.cpp +14 -8
  32. package/src/duckdb/src/common/printer.cpp +1 -1
  33. package/src/duckdb/src/common/string_util.cpp +8 -4
  34. package/src/duckdb/src/common/types/partitioned_column_data.cpp +1 -0
  35. package/src/duckdb/src/common/types/time.cpp +1 -1
  36. package/src/duckdb/src/common/types/timestamp.cpp +35 -4
  37. package/src/duckdb/src/common/types.cpp +37 -11
  38. package/src/duckdb/src/execution/column_binding_resolver.cpp +5 -2
  39. package/src/duckdb/src/execution/index/art/art.cpp +117 -67
  40. package/src/duckdb/src/execution/index/art/art_key.cpp +24 -12
  41. package/src/duckdb/src/execution/index/art/leaf.cpp +7 -8
  42. package/src/duckdb/src/execution/index/art/node.cpp +13 -27
  43. package/src/duckdb/src/execution/index/art/node16.cpp +5 -8
  44. package/src/duckdb/src/execution/index/art/node256.cpp +3 -5
  45. package/src/duckdb/src/execution/index/art/node4.cpp +4 -7
  46. package/src/duckdb/src/execution/index/art/node48.cpp +5 -8
  47. package/src/duckdb/src/execution/index/art/prefix.cpp +2 -3
  48. package/src/duckdb/src/execution/operator/aggregate/physical_window.cpp +6 -27
  49. package/src/duckdb/src/execution/operator/helper/physical_reset.cpp +1 -9
  50. package/src/duckdb/src/execution/operator/helper/physical_set.cpp +1 -9
  51. package/src/duckdb/src/execution/operator/join/physical_iejoin.cpp +7 -9
  52. package/src/duckdb/src/execution/operator/persistent/base_csv_reader.cpp +6 -11
  53. package/src/duckdb/src/execution/operator/persistent/buffered_csv_reader.cpp +13 -13
  54. package/src/duckdb/src/execution/operator/persistent/parallel_csv_reader.cpp +1 -1
  55. package/src/duckdb/src/execution/operator/schema/physical_detach.cpp +37 -0
  56. package/src/duckdb/src/execution/operator/schema/physical_drop.cpp +0 -5
  57. package/src/duckdb/src/execution/physical_operator.cpp +6 -6
  58. package/src/duckdb/src/execution/physical_plan/plan_simple.cpp +4 -0
  59. package/src/duckdb/src/execution/physical_plan_generator.cpp +1 -0
  60. package/src/duckdb/src/function/pragma/pragma_queries.cpp +38 -11
  61. package/src/duckdb/src/function/scalar/generic/current_setting.cpp +2 -2
  62. package/src/duckdb/src/function/scalar/list/array_slice.cpp +2 -3
  63. package/src/duckdb/src/function/scalar/map/map.cpp +69 -21
  64. package/src/duckdb/src/function/scalar/string/like.cpp +6 -3
  65. package/src/duckdb/src/function/table/read_csv.cpp +17 -8
  66. package/src/duckdb/src/function/table/system/duckdb_temporary_files.cpp +59 -0
  67. package/src/duckdb/src/function/table/system_functions.cpp +1 -0
  68. package/src/duckdb/src/function/table/table_scan.cpp +3 -0
  69. package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
  70. package/src/duckdb/src/include/duckdb/catalog/catalog.hpp +7 -1
  71. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/duck_index_entry.hpp +1 -1
  72. package/src/duckdb/src/include/duckdb/catalog/catalog_entry/index_catalog_entry.hpp +1 -1
  73. package/src/duckdb/src/include/duckdb/common/bind_helpers.hpp +2 -0
  74. package/src/duckdb/src/include/duckdb/common/enums/logical_operator_type.hpp +1 -0
  75. package/src/duckdb/src/include/duckdb/common/enums/physical_operator_type.hpp +1 -0
  76. package/src/duckdb/src/include/duckdb/common/enums/statement_type.hpp +3 -2
  77. package/src/duckdb/src/include/duckdb/common/enums/wal_type.hpp +3 -0
  78. package/src/duckdb/src/include/duckdb/common/exception.hpp +10 -0
  79. package/src/duckdb/src/include/duckdb/common/file_system.hpp +1 -0
  80. package/src/duckdb/src/include/duckdb/common/hive_partitioning.hpp +9 -1
  81. package/src/duckdb/src/include/duckdb/common/radix_partitioning.hpp +4 -4
  82. package/src/duckdb/src/include/duckdb/common/string_util.hpp +9 -2
  83. package/src/duckdb/src/include/duckdb/common/types/timestamp.hpp +5 -1
  84. package/src/duckdb/src/include/duckdb/execution/index/art/art.hpp +37 -41
  85. package/src/duckdb/src/include/duckdb/execution/index/art/art_key.hpp +8 -11
  86. package/src/duckdb/src/include/duckdb/execution/operator/persistent/base_csv_reader.hpp +1 -3
  87. package/src/duckdb/src/include/duckdb/execution/operator/persistent/buffered_csv_reader.hpp +0 -2
  88. package/src/duckdb/src/include/duckdb/execution/operator/persistent/csv_reader_options.hpp +2 -0
  89. package/src/duckdb/src/include/duckdb/execution/operator/schema/physical_detach.hpp +32 -0
  90. package/src/duckdb/src/include/duckdb/function/scalar/string_functions.hpp +2 -1
  91. package/src/duckdb/src/include/duckdb/function/table/system_functions.hpp +4 -0
  92. package/src/duckdb/src/include/duckdb/main/client_data.hpp +2 -2
  93. package/src/duckdb/src/include/duckdb/main/config.hpp +2 -3
  94. package/src/duckdb/src/include/duckdb/main/{extension_functions.hpp → extension_entries.hpp} +27 -5
  95. package/src/duckdb/src/include/duckdb/main/extension_helper.hpp +11 -1
  96. package/src/duckdb/src/include/duckdb/main/settings.hpp +9 -0
  97. package/src/duckdb/src/include/duckdb/parallel/pipeline_executor.hpp +0 -7
  98. package/src/duckdb/src/include/duckdb/parser/parsed_data/create_database_info.hpp +0 -4
  99. package/src/duckdb/src/include/duckdb/parser/parsed_data/detach_info.hpp +32 -0
  100. package/src/duckdb/src/include/duckdb/parser/query_node/select_node.hpp +1 -1
  101. package/src/duckdb/src/include/duckdb/parser/sql_statement.hpp +2 -2
  102. package/src/duckdb/src/include/duckdb/parser/statement/copy_statement.hpp +1 -1
  103. package/src/duckdb/src/include/duckdb/parser/statement/detach_statement.hpp +29 -0
  104. package/src/duckdb/src/include/duckdb/parser/statement/list.hpp +1 -0
  105. package/src/duckdb/src/include/duckdb/parser/statement/select_statement.hpp +3 -3
  106. package/src/duckdb/src/include/duckdb/parser/tableref/subqueryref.hpp +1 -1
  107. package/src/duckdb/src/include/duckdb/parser/tokens.hpp +1 -0
  108. package/src/duckdb/src/include/duckdb/parser/transformer.hpp +1 -0
  109. package/src/duckdb/src/include/duckdb/planner/binder.hpp +4 -0
  110. package/src/duckdb/src/include/duckdb/planner/expression_binder/index_binder.hpp +10 -3
  111. package/src/duckdb/src/include/duckdb/planner/operator/logical_execute.hpp +1 -5
  112. package/src/duckdb/src/include/duckdb/planner/operator/logical_show.hpp +1 -2
  113. package/src/duckdb/src/include/duckdb/storage/buffer_manager.hpp +8 -0
  114. package/src/duckdb/src/include/duckdb/storage/data_table.hpp +7 -1
  115. package/src/duckdb/src/include/duckdb/storage/index.hpp +47 -38
  116. package/src/duckdb/src/include/duckdb/storage/storage_extension.hpp +7 -0
  117. package/src/duckdb/src/include/duckdb/storage/table/update_segment.hpp +2 -0
  118. package/src/duckdb/src/include/duckdb/storage/write_ahead_log.hpp +7 -0
  119. package/src/duckdb/src/main/client_context.cpp +2 -0
  120. package/src/duckdb/src/main/config.cpp +1 -0
  121. package/src/duckdb/src/main/database.cpp +14 -5
  122. package/src/duckdb/src/main/extension/extension_alias.cpp +2 -1
  123. package/src/duckdb/src/main/extension/extension_helper.cpp +15 -0
  124. package/src/duckdb/src/main/extension/extension_install.cpp +60 -16
  125. package/src/duckdb/src/main/extension/extension_load.cpp +62 -13
  126. package/src/duckdb/src/main/settings/settings.cpp +16 -0
  127. package/src/duckdb/src/optimizer/statistics/operator/propagate_join.cpp +2 -6
  128. package/src/duckdb/src/parallel/pipeline_executor.cpp +1 -55
  129. package/src/duckdb/src/parser/parsed_data/create_index_info.cpp +3 -0
  130. package/src/duckdb/src/parser/statement/copy_statement.cpp +2 -13
  131. package/src/duckdb/src/parser/statement/delete_statement.cpp +3 -0
  132. package/src/duckdb/src/parser/statement/detach_statement.cpp +15 -0
  133. package/src/duckdb/src/parser/statement/insert_statement.cpp +9 -0
  134. package/src/duckdb/src/parser/statement/update_statement.cpp +3 -0
  135. package/src/duckdb/src/parser/transform/expression/transform_case.cpp +3 -3
  136. package/src/duckdb/src/parser/transform/statement/transform_create_database.cpp +0 -1
  137. package/src/duckdb/src/parser/transform/statement/transform_detach.cpp +19 -0
  138. package/src/duckdb/src/parser/transformer.cpp +2 -0
  139. package/src/duckdb/src/planner/bind_context.cpp +1 -1
  140. package/src/duckdb/src/planner/binder/expression/bind_aggregate_expression.cpp +3 -0
  141. package/src/duckdb/src/planner/binder/statement/bind_copy.cpp +7 -14
  142. package/src/duckdb/src/planner/binder/statement/bind_create.cpp +16 -14
  143. package/src/duckdb/src/planner/binder/statement/bind_create_table.cpp +13 -0
  144. package/src/duckdb/src/planner/binder/statement/bind_detach.cpp +19 -0
  145. package/src/duckdb/src/planner/binder/statement/bind_drop.cpp +29 -4
  146. package/src/duckdb/src/planner/binder/statement/bind_insert.cpp +22 -1
  147. package/src/duckdb/src/planner/binder/tableref/bind_joinref.cpp +2 -1
  148. package/src/duckdb/src/planner/binder.cpp +2 -0
  149. package/src/duckdb/src/planner/expression_binder/index_binder.cpp +32 -1
  150. package/src/duckdb/src/planner/expression_binder/lateral_binder.cpp +21 -5
  151. package/src/duckdb/src/planner/logical_operator.cpp +6 -1
  152. package/src/duckdb/src/planner/planner.cpp +1 -0
  153. package/src/duckdb/src/storage/buffer_manager.cpp +105 -26
  154. package/src/duckdb/src/storage/compression/bitpacking.cpp +16 -7
  155. package/src/duckdb/src/storage/data_table.cpp +66 -3
  156. package/src/duckdb/src/storage/index.cpp +1 -1
  157. package/src/duckdb/src/storage/local_storage.cpp +1 -1
  158. package/src/duckdb/src/storage/storage_info.cpp +2 -1
  159. package/src/duckdb/src/storage/table/column_data.cpp +4 -2
  160. package/src/duckdb/src/storage/table/update_segment.cpp +15 -0
  161. package/src/duckdb/src/storage/table_index_list.cpp +1 -2
  162. package/src/duckdb/src/storage/wal_replay.cpp +68 -0
  163. package/src/duckdb/src/storage/write_ahead_log.cpp +21 -1
  164. package/src/duckdb/src/transaction/commit_state.cpp +5 -2
  165. package/src/duckdb/third_party/concurrentqueue/blockingconcurrentqueue.h +2 -2
  166. package/src/duckdb/third_party/fmt/include/fmt/core.h +1 -2
  167. package/src/duckdb/third_party/libpg_query/include/nodes/nodes.hpp +1 -0
  168. package/src/duckdb/third_party/libpg_query/include/nodes/parsenodes.hpp +14 -0
  169. package/src/duckdb/third_party/libpg_query/include/parser/gram.hpp +530 -1006
  170. package/src/duckdb/third_party/libpg_query/src_backend_parser_gram.cpp +17659 -17626
  171. package/src/duckdb/third_party/thrift/thrift/Thrift.h +8 -2
  172. package/src/duckdb/ub_extension_icu_third_party_icu_i18n.cpp +4 -4
  173. package/src/duckdb/ub_src_execution_operator_schema.cpp +2 -0
  174. package/src/duckdb/ub_src_function_table_system.cpp +2 -0
  175. package/src/duckdb/ub_src_parser_statement.cpp +2 -0
  176. package/src/duckdb/ub_src_parser_transform_statement.cpp +2 -0
  177. package/src/duckdb/ub_src_planner_binder_statement.cpp +2 -0
  178. package/src/statement.cpp +46 -12
  179. package/test/arrow.test.ts +3 -3
  180. package/test/prepare.test.ts +39 -1
  181. package/test/typescript_decls.test.ts +1 -1
  182. package/src/duckdb/src/include/duckdb/function/create_database_extension.hpp +0 -37
@@ -531,6 +531,22 @@ Value ExplainOutputSetting::GetSetting(ClientContext &context) {
531
531
  }
532
532
  }
533
533
 
534
+ //===--------------------------------------------------------------------===//
535
+ // Extension Directory Setting
536
+ //===--------------------------------------------------------------------===//
537
+ void ExtensionDirectorySetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) {
538
+ auto new_directory = input.ToString();
539
+ config.options.extension_directory = input.ToString();
540
+ }
541
+
542
+ void ExtensionDirectorySetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) {
543
+ config.options.extension_directory = DBConfig().options.extension_directory;
544
+ }
545
+
546
+ Value ExtensionDirectorySetting::GetSetting(ClientContext &context) {
547
+ return Value(DBConfig::GetConfig(context).options.extension_directory);
548
+ }
549
+
534
550
  //===--------------------------------------------------------------------===//
535
551
  // External Threads Setting
536
552
  //===--------------------------------------------------------------------===//
@@ -83,12 +83,8 @@ void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, uniq
83
83
  *node_ptr = std::move(cross_product);
84
84
  return;
85
85
  }
86
- case JoinType::INNER:
87
- case JoinType::LEFT:
88
- case JoinType::RIGHT:
89
- case JoinType::OUTER: {
90
- // inner/left/right/full outer join, replace with cross product
91
- // since the condition is always true, left/right/outer join are equivalent to inner join here
86
+ case JoinType::INNER: {
87
+ // inner, replace with cross product
92
88
  auto cross_product =
93
89
  LogicalCrossProduct::Create(std::move(join.children[0]), std::move(join.children[1]));
94
90
  *node_ptr = std::move(cross_product);
@@ -114,52 +114,6 @@ OperatorResultType PipelineExecutor::ExecutePushInternal(DataChunk &input, idx_t
114
114
  }
115
115
  }
116
116
 
117
- // Pull a single DataChunk from the pipeline by flushing any operators holding cached output
118
- void PipelineExecutor::FlushCachingOperatorsPull(DataChunk &result) {
119
- idx_t start_idx = IsFinished() ? idx_t(finished_processing_idx) : 0;
120
- idx_t op_idx = start_idx;
121
- while (op_idx < pipeline.operators.size()) {
122
- if (!pipeline.operators[op_idx]->RequiresFinalExecute()) {
123
- op_idx++;
124
- continue;
125
- }
126
-
127
- OperatorFinalizeResultType finalize_result;
128
- DataChunk &curr_chunk =
129
- op_idx + 1 >= intermediate_chunks.size() ? final_chunk : *intermediate_chunks[op_idx + 1];
130
-
131
- if (pending_final_execute) {
132
- // Still have a cached chunk from a last pull, reuse chunk
133
- finalize_result = cached_final_execute_result;
134
- } else {
135
- // Flush the current operator
136
- auto current_operator = pipeline.operators[op_idx];
137
- StartOperator(current_operator);
138
- finalize_result = current_operator->FinalExecute(context, curr_chunk, *current_operator->op_state,
139
- *intermediate_states[op_idx]);
140
- EndOperator(current_operator, &curr_chunk);
141
- }
142
-
143
- auto execute_result = Execute(curr_chunk, result, op_idx + 1);
144
-
145
- if (execute_result == OperatorResultType::HAVE_MORE_OUTPUT) {
146
- pending_final_execute = true;
147
- cached_final_execute_result = finalize_result;
148
- } else {
149
- pending_final_execute = false;
150
- if (finalize_result == OperatorFinalizeResultType::FINISHED) {
151
- FinishProcessing(op_idx);
152
- op_idx++;
153
- }
154
- }
155
-
156
- // Some non-empty result was pulled from some caching operator, we're done for this pull
157
- if (result.size() > 0) {
158
- break;
159
- }
160
- }
161
- }
162
-
163
117
  // Push all remaining cached operator output through the pipeline
164
118
  void PipelineExecutor::FlushCachingOperatorsPush() {
165
119
  idx_t start_idx = IsFinished() ? idx_t(finished_processing_idx) : 0;
@@ -223,21 +177,13 @@ void PipelineExecutor::ExecutePull(DataChunk &result) {
223
177
  D_ASSERT(!pipeline.sink);
224
178
  auto &source_chunk = pipeline.operators.empty() ? result : *intermediate_chunks[0];
225
179
  while (result.size() == 0) {
226
- if (source_empty) {
227
- FlushCachingOperatorsPull(result);
228
- break;
229
- }
230
-
231
180
  if (in_process_operators.empty()) {
232
181
  source_chunk.Reset();
233
182
  FetchFromSource(source_chunk);
234
-
235
183
  if (source_chunk.size() == 0) {
236
- source_empty = true;
237
- continue;
184
+ break;
238
185
  }
239
186
  }
240
-
241
187
  if (!pipeline.operators.empty()) {
242
188
  auto state = Execute(source_chunk, result);
243
189
  if (state == OperatorResultType::FINISHED) {
@@ -16,6 +16,9 @@ unique_ptr<CreateInfo> CreateIndexInfo::Copy() const {
16
16
  for (auto &expr : expressions) {
17
17
  result->expressions.push_back(expr->Copy());
18
18
  }
19
+ for (auto &expr : parsed_expressions) {
20
+ result->parsed_expressions.push_back(expr->Copy());
21
+ }
19
22
 
20
23
  result->scan_types = scan_types;
21
24
  result->names = names;
@@ -11,16 +11,6 @@ CopyStatement::CopyStatement(const CopyStatement &other) : SQLStatement(other),
11
11
  }
12
12
  }
13
13
 
14
- string ConvertOptionValueToString(const Value &val) {
15
- auto type = val.type().id();
16
- switch (type) {
17
- case LogicalTypeId::VARCHAR:
18
- return KeywordHelper::WriteOptionallyQuoted(val.ToString());
19
- default:
20
- return val.ToString();
21
- }
22
- }
23
-
24
14
  string CopyStatement::CopyOptionsToString(const string &format,
25
15
  const case_insensitive_map_t<vector<Value>> &options) const {
26
16
  if (format.empty() && options.empty()) {
@@ -45,15 +35,14 @@ string CopyStatement::CopyOptionsToString(const string &format,
45
35
  // Options like HEADER don't need an explicit value
46
36
  // just providing the name already sets it to true
47
37
  } else if (values.size() == 1) {
48
- result += ConvertOptionValueToString(values[0]);
38
+ result += values[0].ToSQLString();
49
39
  } else {
50
40
  result += "( ";
51
41
  for (idx_t i = 0; i < values.size(); i++) {
52
- auto &value = values[i];
53
42
  if (i) {
54
43
  result += ", ";
55
44
  }
56
- result += KeywordHelper::WriteOptionallyQuoted(value.ToString());
45
+ result += values[i].ToSQLString();
57
46
  }
58
47
  result += " )";
59
48
  }
@@ -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);
@@ -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