Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions src/duckdb/src/common/sorting/hashed_sort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,9 @@ HashedSortLocalSinkState::HashedSortLocalSinkState(ExecutionContext &context, co
}
// OVER(...)
payload_chunk.Initialize(allocator, payload_types);
} else {
unsorted = make_uniq<ColumnDataCollection>(context.client, hashed_sort.payload_types);
unsorted->InitializeAppend(unsorted_append);
}
}

Expand Down Expand Up @@ -369,10 +372,6 @@ SinkResultType HashedSort::Sink(ExecutionContext &context, DataChunk &input_chun

// OVER()
if (gstate.hashed_sort.sort_col_count == 0) {
if (!lstate.unsorted) {
lstate.unsorted = make_uniq<ColumnDataCollection>(context.client, payload_types);
lstate.unsorted->InitializeAppend(lstate.unsorted_append);
}
lstate.unsorted->Append(lstate.unsorted_append, input_chunk);
return SinkResultType::NEED_MORE_INPUT;
}
Expand Down
6 changes: 4 additions & 2 deletions src/duckdb/src/execution/operator/schema/physical_attach.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ SourceResultType PhysicalAttach::GetData(ExecutionContext &context, DataChunk &c
}
}

// Get the database type and attach the database.
db_manager.GetDatabaseType(context.client, *info, config, options);
// attach the database.
auto attached_db = db_manager.AttachDatabase(context.client, *info, options);
if (!attached_db) {
return SourceResultType::FINISHED;
}

//! Initialize the database.
attached_db->Initialize(context.client);
Expand Down
6 changes: 3 additions & 3 deletions src/duckdb/src/function/table/version/pragma_version.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef DUCKDB_PATCH_VERSION
#define DUCKDB_PATCH_VERSION "0-dev4099"
#define DUCKDB_PATCH_VERSION "0-dev4107"
#endif
#ifndef DUCKDB_MINOR_VERSION
#define DUCKDB_MINOR_VERSION 4
Expand All @@ -8,10 +8,10 @@
#define DUCKDB_MAJOR_VERSION 1
#endif
#ifndef DUCKDB_VERSION
#define DUCKDB_VERSION "v1.4.0-dev4099"
#define DUCKDB_VERSION "v1.4.0-dev4107"
#endif
#ifndef DUCKDB_SOURCE_ID
#define DUCKDB_SOURCE_ID "a00499ff6c"
#define DUCKDB_SOURCE_ID "82446e8a32"
#endif
#include "duckdb/function/table/system_functions.hpp"
#include "duckdb/main/database.hpp"
Expand Down
12 changes: 7 additions & 5 deletions src/duckdb/src/include/duckdb/main/attached_database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class StorageExtension;
class DatabaseManager;

struct AttachInfo;
struct StoredDatabasePath;

enum class AttachedDatabaseType {
READ_WRITE_DATABASE,
Expand All @@ -31,11 +32,13 @@ enum class AttachedDatabaseType {
TEMP_DATABASE,
};

class DatabaseFilePathManager;

struct StoredDatabasePath {
StoredDatabasePath(DatabaseManager &manager, string path, const string &name);
StoredDatabasePath(DatabaseFilePathManager &manager, string path, const string &name);
~StoredDatabasePath();

DatabaseManager &manager;
DatabaseFilePathManager &manager;
string path;
};

Expand All @@ -55,6 +58,8 @@ struct AttachOptions {
unordered_map<string, Value> options;
//! (optionally) a catalog can be provided with a default table
QualifiedName default_table;
//! The stored database path (in the path manager)
unique_ptr<StoredDatabasePath> stored_database_path;
};

//! The AttachedDatabase represents an attached database instance.
Expand Down Expand Up @@ -102,9 +107,6 @@ class AttachedDatabase : public CatalogEntry, public enable_shared_from_this<Att
static bool NameIsReserved(const string &name);
static string ExtractDatabaseName(const string &dbpath, FileSystem &fs);

private:
void InsertDatabasePath(const string &path);

private:
DatabaseInstance &db;
unique_ptr<StoredDatabasePath> stored_database_path;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,20 @@
#include "duckdb/common/common.hpp"
#include "duckdb/common/mutex.hpp"
#include "duckdb/common/case_insensitive_map.hpp"
#include "duckdb/common/enums/on_create_conflict.hpp"

namespace duckdb {
struct AttachInfo;
struct AttachOptions;

enum class InsertDatabasePathResult { SUCCESS, ALREADY_EXISTS };

//! The DatabaseFilePathManager is used to ensure we only ever open a single database file once
class DatabaseFilePathManager {
public:
void CheckPathConflict(const string &path, const string &name) const;
idx_t ApproxDatabaseCount() const;
void InsertDatabasePath(const string &path, const string &name);
InsertDatabasePathResult InsertDatabasePath(const string &path, const string &name, OnCreateConflict on_conflict,
AttachOptions &options);
void EraseDatabasePath(const string &path);

private:
Expand Down
6 changes: 1 addition & 5 deletions src/duckdb/src/include/duckdb/main/database_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,7 @@ class DatabaseManager {
void SetDefaultDatabase(ClientContext &context, const string &new_value);

//! Inserts a path to name mapping to the database paths map
void InsertDatabasePath(const string &path, const string &name);
//! Erases a path from the database paths map
void EraseDatabasePath(const string &path);
//! Check if a path has a conflict
void CheckPathConflict(const string &path, const string &name);
InsertDatabasePathResult InsertDatabasePath(const AttachInfo &info, AttachOptions &options);

//! Returns the database type. This might require checking the header of the file, in which case the file handle is
//! necessary. We can only grab the file handle, if it is not yet held, even for uncommitted changes. Thus, we have
Expand Down
16 changes: 4 additions & 12 deletions src/duckdb/src/main/attached_database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,17 @@

namespace duckdb {

StoredDatabasePath::StoredDatabasePath(DatabaseManager &manager, string path_p, const string &name)
StoredDatabasePath::StoredDatabasePath(DatabaseFilePathManager &manager, string path_p, const string &name)
: manager(manager), path(std::move(path_p)) {
manager.InsertDatabasePath(path, name);
}

StoredDatabasePath::~StoredDatabasePath() {
manager.EraseDatabasePath(path);
}

//===--------------------------------------------------------------------===//
// Attach Options
//===--------------------------------------------------------------------===//

AttachOptions::AttachOptions(const DBConfigOptions &options)
: access_mode(options.access_mode), db_type(options.database_type) {
}
Expand Down Expand Up @@ -102,7 +101,7 @@ AttachedDatabase::AttachedDatabase(DatabaseInstance &db, Catalog &catalog_p, str
}
// We create the storage after the catalog to guarantee we allow extensions to instantiate the DuckCatalog.
catalog = make_uniq<DuckCatalog>(*this);
InsertDatabasePath(file_path_p);
stored_database_path = std::move(options.stored_database_path);
storage = make_uniq<SingleFileStorageManager>(*this, std::move(file_path_p), options);
transaction_manager = make_uniq<DuckTransactionManager>(*this);
internal = true;
Expand All @@ -120,11 +119,11 @@ AttachedDatabase::AttachedDatabase(DatabaseInstance &db, Catalog &catalog_p, Sto

optional_ptr<StorageExtensionInfo> storage_info = storage_extension->storage_info.get();
catalog = storage_extension->attach(storage_info, context, *this, name, info, options);
stored_database_path = std::move(options.stored_database_path);
if (!catalog) {
throw InternalException("AttachedDatabase - attach function did not return a catalog");
}
if (catalog->IsDuckCatalog()) {
InsertDatabasePath(info.path);
// The attached database uses the DuckCatalog.
storage = make_uniq<SingleFileStorageManager>(*this, info.path, options);
}
Expand Down Expand Up @@ -152,13 +151,6 @@ bool AttachedDatabase::IsReadOnly() const {
return type == AttachedDatabaseType::READ_ONLY_DATABASE;
}

void AttachedDatabase::InsertDatabasePath(const string &path) {
if (path.empty() || path == IN_MEMORY_PATH) {
return;
}
stored_database_path = make_uniq<StoredDatabasePath>(db.GetDatabaseManager(), path, name);
}

bool AttachedDatabase::NameIsReserved(const string &name) {
return name == DEFAULT_SCHEMA || name == TEMP_CATALOG || name == SYSTEM_CATALOG;
}
Expand Down
7 changes: 2 additions & 5 deletions src/duckdb/src/main/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,17 +298,14 @@ void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_conf
// initialize the secret manager
config.secret_manager->Initialize(*this);

// resolve the type of teh database we are opening
// resolve the type of the database we are opening
auto &fs = FileSystem::GetFileSystem(*this);
DBPathAndType::ResolveDatabaseType(fs, config.options.database_path, config.options.database_type);

// initialize the system catalog
db_manager->InitializeSystemCatalog();

if (config.options.database_type == "duckdb") {
config.options.database_type = string();
}
if (!config.options.database_type.empty()) {
if (!config.options.database_type.empty() && !StringUtil::CIEquals(config.options.database_type, "duckdb")) {
// if we are opening an extension database - load the extension
if (!config.file_system) {
throw InternalException("No file system!?");
Expand Down
27 changes: 11 additions & 16 deletions src/duckdb/src/main/database_file_path_manager.cpp
Original file line number Diff line number Diff line change
@@ -1,39 +1,34 @@
#include "duckdb/main/database_file_path_manager.hpp"
#include "duckdb/common/exception/binder_exception.hpp"
#include "duckdb/parser/parsed_data/attach_info.hpp"
#include "duckdb/main/attached_database.hpp"

namespace duckdb {

void DatabaseFilePathManager::CheckPathConflict(const string &path, const string &name) const {
if (path.empty() || path == IN_MEMORY_PATH) {
return;
}

lock_guard<mutex> path_lock(db_paths_lock);
auto entry = db_paths_to_name.find(path);
if (entry != db_paths_to_name.end()) {
throw BinderException("Unique file handle conflict: Cannot attach \"%s\" - the database file \"%s\" is already "
"attached by database \"%s\"",
name, path, entry->second);
}
}

idx_t DatabaseFilePathManager::ApproxDatabaseCount() const {
lock_guard<mutex> path_lock(db_paths_lock);
return db_paths_to_name.size();
}

void DatabaseFilePathManager::InsertDatabasePath(const string &path, const string &name) {
InsertDatabasePathResult DatabaseFilePathManager::InsertDatabasePath(const string &path, const string &name,
OnCreateConflict on_conflict,
AttachOptions &options) {
if (path.empty() || path == IN_MEMORY_PATH) {
return;
return InsertDatabasePathResult::SUCCESS;
}

lock_guard<mutex> path_lock(db_paths_lock);
auto entry = db_paths_to_name.emplace(path, name);
if (!entry.second) {
if (on_conflict == OnCreateConflict::IGNORE_ON_CONFLICT && entry.first->second == name) {
return InsertDatabasePathResult::ALREADY_EXISTS;
}
throw BinderException("Unique file handle conflict: Cannot attach \"%s\" - the database file \"%s\" is already "
"attached by database \"%s\"",
name, path, entry.first->second);
}
options.stored_database_path = make_uniq<StoredDatabasePath>(*this, path, name);
return InsertDatabasePathResult::SUCCESS;
}

void DatabaseFilePathManager::EraseDatabasePath(const string &path) {
Expand Down
27 changes: 15 additions & 12 deletions src/duckdb/src/main/database_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ optional_ptr<AttachedDatabase> DatabaseManager::GetDatabase(ClientContext &conte

shared_ptr<AttachedDatabase> DatabaseManager::AttachDatabase(ClientContext &context, AttachInfo &info,
AttachOptions &options) {
auto &config = DBConfig::GetConfig(context);
if (options.db_type.empty() || StringUtil::CIEquals(options.db_type, "duckdb")) {
if (InsertDatabasePath(info, options) == InsertDatabasePathResult::ALREADY_EXISTS) {
return nullptr;
}
}
GetDatabaseType(context, info, config, options);
if (!options.db_type.empty()) {
// we only need to prevent duplicate opening of DuckDB files
// if this is not a DuckDB file but e.g. a CSV or Parquet file, we don't need to do this duplicate protection
options.stored_database_path.reset();
}
if (AttachedDatabase::NameIsReserved(info.name)) {
throw BinderException("Attached database name \"%s\" cannot be used because it is a reserved name", info.name);
}
Expand Down Expand Up @@ -157,20 +169,12 @@ shared_ptr<AttachedDatabase> DatabaseManager::DetachInternal(const string &name)
return attached_db;
}

void DatabaseManager::CheckPathConflict(const string &path, const string &name) {
path_manager->CheckPathConflict(path, name);
}

idx_t DatabaseManager::ApproxDatabaseCount() {
return path_manager->ApproxDatabaseCount();
}

void DatabaseManager::InsertDatabasePath(const string &path, const string &name) {
path_manager->InsertDatabasePath(path, name);
}

void DatabaseManager::EraseDatabasePath(const string &path) {
path_manager->EraseDatabasePath(path);
InsertDatabasePathResult DatabaseManager::InsertDatabasePath(const AttachInfo &info, AttachOptions &options) {
return path_manager->InsertDatabasePath(info.path, info.name, info.on_conflict, options);
}

vector<string> DatabaseManager::GetAttachedDatabasePaths() {
Expand All @@ -195,15 +199,14 @@ void DatabaseManager::GetDatabaseType(ClientContext &context, AttachInfo &info,
AttachOptions &options) {

// Test if the database is a DuckDB database file.
if (StringUtil::CIEquals(options.db_type, "DUCKDB")) {
if (StringUtil::CIEquals(options.db_type, "duckdb")) {
options.db_type = "";
return;
}

// Try to extract the database type from the path.
if (options.db_type.empty()) {
auto &fs = FileSystem::GetFileSystem(context);
CheckPathConflict(info.path, info.name);
DBPathAndType::CheckMagicBytes(QueryContext(context), fs, info.path, options.db_type);
}

Expand Down
Loading