duckdb 0.8.1-dev327.0 → 0.8.1-dev355.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "duckdb",
3
3
  "main": "./lib/duckdb.js",
4
4
  "types": "./lib/duckdb.d.ts",
5
- "version": "0.8.1-dev327.0",
5
+ "version": "0.8.1-dev355.0",
6
6
  "description": "DuckDB node.js API",
7
7
  "gypfile": true,
8
8
  "dependencies": {
@@ -1270,6 +1270,7 @@ void WindowLocalSourceState::GeneratePartition(WindowGlobalSinkState &gstate, co
1270
1270
  // Overwrite the collections with the sorted data
1271
1271
  hash_group = std::move(gsink.hash_groups[hash_bin]);
1272
1272
  hash_group->ComputeMasks(partition_mask, order_mask);
1273
+ external = hash_group->global_sort->external;
1273
1274
  MaterializeSortedData();
1274
1275
  } else {
1275
1276
  return;
@@ -14,7 +14,6 @@ namespace duckdb {
14
14
  //===--------------------------------------------------------------------===//
15
15
  // Source
16
16
  //===--------------------------------------------------------------------===//
17
-
18
17
  SourceResultType PhysicalAttach::GetData(ExecutionContext &context, DataChunk &chunk,
19
18
  OperatorSourceInput &input) const {
20
19
  // parse the options
@@ -1,8 +1,8 @@
1
1
  #ifndef DUCKDB_VERSION
2
- #define DUCKDB_VERSION "0.8.1-dev327"
2
+ #define DUCKDB_VERSION "0.8.1-dev355"
3
3
  #endif
4
4
  #ifndef DUCKDB_SOURCE_ID
5
- #define DUCKDB_SOURCE_ID "57912b60a6"
5
+ #define DUCKDB_SOURCE_ID "e9b683ce15"
6
6
  #endif
7
7
  #include "duckdb/function/table/system_functions.hpp"
8
8
  #include "duckdb/main/database.hpp"
@@ -40,7 +40,7 @@ public:
40
40
  //! Create an attached database instance with the specified storage extension
41
41
  AttachedDatabase(DatabaseInstance &db, Catalog &catalog, StorageExtension &ext, string name, AttachInfo &info,
42
42
  AccessMode access_mode);
43
- ~AttachedDatabase();
43
+ ~AttachedDatabase() override;
44
44
 
45
45
  void Initialize();
46
46
 
@@ -57,6 +57,8 @@ public:
57
57
  bool IsSystem() const;
58
58
  bool IsTemporary() const;
59
59
  bool IsReadOnly() const;
60
+ bool IsInitialDatabase() const;
61
+ void SetInitialDatabase();
60
62
 
61
63
  static string ExtractDatabaseName(const string &dbpath);
62
64
 
@@ -67,6 +69,7 @@ private:
67
69
  unique_ptr<TransactionManager> transaction_manager;
68
70
  AttachedDatabaseType type;
69
71
  optional_ptr<Catalog> parent_catalog;
72
+ bool is_initial_database = false;
70
73
  };
71
74
 
72
75
  } // namespace duckdb
@@ -45,6 +45,8 @@ public:
45
45
 
46
46
  //! Contains all bindings that need to be updated
47
47
  vector<ReplaceBinding> replace_bindings;
48
+ //! Stores the table index of the former child of the LOGICAL_UNNEST
49
+ idx_t overwritten_tbl_idx;
48
50
  };
49
51
 
50
52
  //! The UnnestRewriter optimizer traverses the logical operator tree and rewrites duplicate
@@ -79,6 +81,8 @@ private:
79
81
  vector<LHSBinding> lhs_bindings;
80
82
  //! Stores the table index of the former child of the LOGICAL_UNNEST
81
83
  idx_t overwritten_tbl_idx;
84
+ //! The number of distinct columns to unnest
85
+ idx_t distinct_unnest_count;
82
86
  };
83
87
 
84
88
  } // namespace duckdb
@@ -124,4 +124,12 @@ Catalog &AttachedDatabase::ParentCatalog() {
124
124
  return *parent_catalog;
125
125
  }
126
126
 
127
+ bool AttachedDatabase::IsInitialDatabase() const {
128
+ return is_initial_database;
129
+ }
130
+
131
+ void AttachedDatabase::SetInitialDatabase() {
132
+ is_initial_database = true;
133
+ }
134
+
127
135
  } // namespace duckdb
@@ -171,6 +171,7 @@ void DatabaseInstance::CreateMainDatabase() {
171
171
  }
172
172
 
173
173
  // initialize the database
174
+ initial_database->SetInitialDatabase();
174
175
  initial_database->Initialize();
175
176
  }
176
177
 
@@ -43,6 +43,11 @@ void DatabaseManager::AddDatabase(ClientContext &context, unique_ptr<AttachedDat
43
43
  }
44
44
 
45
45
  void DatabaseManager::DetachDatabase(ClientContext &context, const string &name, OnEntryNotFound if_not_found) {
46
+ if (GetDefaultDatabase(context) == name) {
47
+ throw BinderException("Cannot detach database \"%s\" because it is the default database. Select a different "
48
+ "database using `USE` to allow detaching this database",
49
+ name);
50
+ }
46
51
  if (!databases->DropEntry(context, name, false, true)) {
47
52
  if (if_not_found == OnEntryNotFound::THROW_EXCEPTION) {
48
53
  throw BinderException("Failed to detach database with name \"%s\": database not found", name);
@@ -26,11 +26,7 @@ void UnnestRewriterPlanUpdater::VisitExpression(unique_ptr<Expression> *expressi
26
26
  for (idx_t i = 0; i < replace_bindings.size(); i++) {
27
27
  if (bound_column_ref.binding == replace_bindings[i].old_binding) {
28
28
  bound_column_ref.binding = replace_bindings[i].new_binding;
29
- }
30
- // previously pointing to the LOGICAL_DELIM_GET
31
- if (bound_column_ref.binding.table_index == replace_bindings[i].old_binding.table_index &&
32
- replace_bindings[i].old_binding.column_index == DConstants::INVALID_INDEX) {
33
- bound_column_ref.binding = replace_bindings[i].new_binding;
29
+ break;
34
30
  }
35
31
  }
36
32
  }
@@ -49,6 +45,7 @@ unique_ptr<LogicalOperator> UnnestRewriter::Optimize(unique_ptr<LogicalOperator>
49
45
 
50
46
  // rearrange the logical operators
51
47
  if (RewriteCandidate(candidate)) {
48
+ updater.overwritten_tbl_idx = overwritten_tbl_idx;
52
49
  // update the bindings of the BOUND_UNNEST expression
53
50
  UpdateBoundUnnestBindings(updater, candidate);
54
51
  // update the sequence of LOGICAL_PROJECTION(s)
@@ -106,7 +103,6 @@ void UnnestRewriter::FindCandidates(unique_ptr<LogicalOperator> *op_ptr,
106
103
  if (curr_op->get()->type == LogicalOperatorType::LOGICAL_UNNEST) {
107
104
  candidates.push_back(op_ptr);
108
105
  }
109
- return;
110
106
  }
111
107
 
112
108
  bool UnnestRewriter::RewriteCandidate(unique_ptr<LogicalOperator> *candidate) {
@@ -147,6 +143,11 @@ bool UnnestRewriter::RewriteCandidate(unique_ptr<LogicalOperator> *candidate) {
147
143
  auto &unnest = curr_op->get()->Cast<LogicalUnnest>();
148
144
  D_ASSERT(unnest.children[0]->type == LogicalOperatorType::LOGICAL_DELIM_GET);
149
145
  overwritten_tbl_idx = unnest.children[0]->Cast<LogicalDelimGet>().table_index;
146
+
147
+ D_ASSERT(!unnest.children.empty());
148
+ auto &delim_get = unnest.children[0]->Cast<LogicalDelimGet>();
149
+ D_ASSERT(delim_get.chunk_types.size() > 1);
150
+ distinct_unnest_count = delim_get.chunk_types.size();
150
151
  unnest.children[0] = std::move(lhs_op);
151
152
 
152
153
  // replace the LOGICAL_DELIM_JOIN with its RHS child operator
@@ -168,10 +169,11 @@ void UnnestRewriter::UpdateRHSBindings(unique_ptr<LogicalOperator> *plan_ptr, un
168
169
  D_ASSERT(curr_op->get()->type == LogicalOperatorType::LOGICAL_PROJECTION);
169
170
  auto &proj = curr_op->get()->Cast<LogicalProjection>();
170
171
 
171
- // pop the two last expressions from all projections (delim_idx and UNNEST column)
172
- D_ASSERT(proj.expressions.size() > 2);
173
- proj.expressions.pop_back();
174
- proj.expressions.pop_back();
172
+ // pop the unnest columns and the delim index
173
+ D_ASSERT(proj.expressions.size() > distinct_unnest_count);
174
+ for (idx_t i = 0; i < distinct_unnest_count; i++) {
175
+ proj.expressions.pop_back();
176
+ }
175
177
 
176
178
  // store all shifted current bindings
177
179
  idx_t tbl_idx = proj.table_index;
@@ -263,14 +265,23 @@ void UnnestRewriter::UpdateBoundUnnestBindings(UnnestRewriterPlanUpdater &update
263
265
  auto &unnest = curr_op->get()->Cast<LogicalUnnest>();
264
266
 
265
267
  D_ASSERT(unnest.children.size() == 1);
266
- auto unnest_child_cols = unnest.children[0]->GetColumnBindings();
267
- for (idx_t delim_col_idx = 0; delim_col_idx < delim_columns.size(); delim_col_idx++) {
268
- for (idx_t child_col_idx = 0; child_col_idx < unnest_child_cols.size(); child_col_idx++) {
269
- if (delim_columns[delim_col_idx].table_index == unnest_child_cols[child_col_idx].table_index) {
270
- ColumnBinding old_binding(overwritten_tbl_idx, DConstants::INVALID_INDEX);
271
- updater.replace_bindings.emplace_back(old_binding, delim_columns[delim_col_idx]);
268
+ auto unnest_cols = unnest.children[0]->GetColumnBindings();
269
+
270
+ for (idx_t i = 0; i < delim_columns.size(); i++) {
271
+ auto delim_binding = delim_columns[i];
272
+
273
+ auto unnest_it = unnest_cols.begin();
274
+ while (unnest_it != unnest_cols.end()) {
275
+ auto unnest_binding = *unnest_it;
276
+
277
+ if (delim_binding.table_index == unnest_binding.table_index) {
278
+ unnest_binding.table_index = overwritten_tbl_idx;
279
+ unnest_binding.column_index++;
280
+ updater.replace_bindings.emplace_back(unnest_binding, delim_binding);
281
+ unnest_cols.erase(unnest_it);
272
282
  break;
273
283
  }
284
+ unnest_it++;
274
285
  }
275
286
  }
276
287
 
@@ -12,6 +12,7 @@
12
12
  #include "duckdb/transaction/transaction_manager.hpp"
13
13
  #include "duckdb/common/serializer/buffered_file_reader.hpp"
14
14
  #include "duckdb/main/attached_database.hpp"
15
+ #include "duckdb/main/database_manager.hpp"
15
16
 
16
17
  namespace duckdb {
17
18
 
@@ -98,6 +99,11 @@ void SingleFileStorageManager::LoadDatabase() {
98
99
  auto &fs = FileSystem::Get(db);
99
100
  auto &config = DBConfig::Get(db);
100
101
  bool truncate_wal = false;
102
+ if (!config.options.enable_external_access) {
103
+ if (!db.IsInitialDatabase()) {
104
+ throw PermissionException("Attaching on-disk databases is disabled through configuration");
105
+ }
106
+ }
101
107
 
102
108
  StorageManagerOptions options;
103
109
  options.read_only = read_only;
@@ -426,7 +426,6 @@ typedef enum PGNodeTag {
426
426
  T_PGImportStmt,
427
427
  T_PGAttachStmt,
428
428
  T_PGDetachStmt,
429
- T_PGCreateDatabaseStmt,
430
429
  T_PGUseStmt,
431
430
 
432
431
  /*