55
66namespace duckdb {
77
8+ DatabasePathInfo::DatabasePathInfo (DatabaseManager &manager, string name_p, AccessMode access_mode)
9+ : name(std::move(name_p)), access_mode(access_mode) {
10+ attached_databases.insert (manager);
11+ }
12+
813idx_t DatabaseFilePathManager::ApproxDatabaseCount () const {
914 lock_guard<mutex> path_lock (db_paths_lock);
1015 return db_paths.size ();
1116}
1217
13- InsertDatabasePathResult DatabaseFilePathManager::InsertDatabasePath (const string &path , const string &name ,
14- OnCreateConflict on_conflict,
18+ InsertDatabasePathResult DatabaseFilePathManager::InsertDatabasePath (DatabaseManager &manager , const string &path ,
19+ const string &name, OnCreateConflict on_conflict,
1520 AttachOptions &options) {
1621 if (path.empty () || path == IN_MEMORY_PATH) {
1722 return InsertDatabasePathResult::SUCCESS;
1823 }
1924
2025 lock_guard<mutex> path_lock (db_paths_lock);
21- auto entry = db_paths.emplace (path, DatabasePathInfo (name, options.access_mode ));
26+ auto entry = db_paths.emplace (path, DatabasePathInfo (manager, name, options.access_mode ));
2227 if (!entry.second ) {
2328 auto &existing = entry.first ->second ;
29+ bool already_exists = false ;
30+ bool attached_in_this_system = false ;
31+ if (on_conflict == OnCreateConflict::IGNORE_ON_CONFLICT && existing.name == name) {
32+ already_exists = true ;
33+ attached_in_this_system = existing.attached_databases .find (manager) != existing.attached_databases .end ();
34+ }
2435 if (options.access_mode == AccessMode::READ_ONLY && existing.access_mode == AccessMode::READ_ONLY) {
36+ if (attached_in_this_system) {
37+ return InsertDatabasePathResult::ALREADY_EXISTS;
38+ }
2539 // all attaches are in read-only mode - there is no conflict, just increase the reference count
40+ existing.attached_databases .insert (manager);
2641 existing.reference_count ++;
2742 } else {
28- if (on_conflict == OnCreateConflict::IGNORE_ON_CONFLICT && existing. name == name ) {
29- if (existing. is_attached ) {
43+ if (already_exists ) {
44+ if (attached_in_this_system ) {
3045 return InsertDatabasePathResult::ALREADY_EXISTS;
3146 }
3247 throw BinderException (
@@ -40,7 +55,7 @@ InsertDatabasePathResult DatabaseFilePathManager::InsertDatabasePath(const strin
4055 name, path, existing.name );
4156 }
4257 }
43- options.stored_database_path = make_uniq<StoredDatabasePath>(*this , path, name);
58+ options.stored_database_path = make_uniq<StoredDatabasePath>(manager, *this , path, name);
4459 return InsertDatabasePathResult::SUCCESS;
4560}
4661
@@ -59,14 +74,14 @@ void DatabaseFilePathManager::EraseDatabasePath(const string &path) {
5974 }
6075}
6176
62- void DatabaseFilePathManager::DetachDatabase (const string &path) {
77+ void DatabaseFilePathManager::DetachDatabase (DatabaseManager &manager, const string &path) {
6378 if (path.empty () || path == IN_MEMORY_PATH) {
6479 return ;
6580 }
6681 lock_guard<mutex> path_lock (db_paths_lock);
6782 auto entry = db_paths.find (path);
6883 if (entry != db_paths.end ()) {
69- entry->second .is_attached = false ;
84+ entry->second .attached_databases . erase (manager) ;
7085 }
7186}
7287
0 commit comments