From 84b079ec18f08408ca877df8f17c76f95b73909e Mon Sep 17 00:00:00 2001 From: Tishj Date: Thu, 26 Oct 2023 09:35:22 +0200 Subject: [PATCH] create catalog entries for dependency management --- src/catalog/catalog_entry/CMakeLists.txt | 2 + .../dependency_catalog_entry.cpp | 12 ++++ .../dependency_set_catalog_entry.cpp | 20 ++++++ src/catalog/dependency_manager.cpp | 68 ++++++++++++++++++- .../dependency_catalog_entry.hpp | 36 ++++++++++ .../dependency_set_catalog_entry.hpp | 37 ++++++++++ .../duckdb/catalog/dependency_manager.hpp | 8 +++ .../duckdb/common/enums/catalog_type.hpp | 4 ++ 8 files changed, 186 insertions(+), 1 deletion(-) create mode 100644 src/catalog/catalog_entry/dependency_catalog_entry.cpp create mode 100644 src/catalog/catalog_entry/dependency_set_catalog_entry.cpp create mode 100644 src/include/duckdb/catalog/catalog_entry/dependency_catalog_entry.hpp create mode 100644 src/include/duckdb/catalog/catalog_entry/dependency_set_catalog_entry.hpp diff --git a/src/catalog/catalog_entry/CMakeLists.txt b/src/catalog/catalog_entry/CMakeLists.txt index 95fd030c15ea..95dd2ebc41a1 100644 --- a/src/catalog/catalog_entry/CMakeLists.txt +++ b/src/catalog/catalog_entry/CMakeLists.txt @@ -15,6 +15,8 @@ add_library_unity( column_dependency_manager.cpp scalar_function_catalog_entry.cpp table_function_catalog_entry.cpp + dependency_set_catalog_entry.cpp + dependency_catalog_entry.cpp view_catalog_entry.cpp) set(ALL_OBJECT_FILES ${ALL_OBJECT_FILES} $ diff --git a/src/catalog/catalog_entry/dependency_catalog_entry.cpp b/src/catalog/catalog_entry/dependency_catalog_entry.cpp new file mode 100644 index 000000000000..eadbcdf938cf --- /dev/null +++ b/src/catalog/catalog_entry/dependency_catalog_entry.cpp @@ -0,0 +1,12 @@ +#include "duckdb/catalog/catalog_entry/dependency_catalog_entry.hpp" + +namespace duckdb { + +DependencyCatalogEntry::DependencyCatalogEntry(Catalog &catalog, const string &name) + : InCatalogEntry(CatalogType::DEPENDENCY_ENTRY, catalog, name) { +} + +DependencyCatalogEntry::~DependencyCatalogEntry() { +} + +} // namespace duckdb diff --git a/src/catalog/catalog_entry/dependency_set_catalog_entry.cpp b/src/catalog/catalog_entry/dependency_set_catalog_entry.cpp new file mode 100644 index 000000000000..e91dce014a02 --- /dev/null +++ b/src/catalog/catalog_entry/dependency_set_catalog_entry.cpp @@ -0,0 +1,20 @@ +#include "duckdb/catalog/catalog_entry/dependency_set_catalog_entry.hpp" + +namespace duckdb { + +DependencySetCatalogEntry::DependencySetCatalogEntry(Catalog &catalog, const string &name) + : InCatalogEntry(CatalogType::DEPENDENCY_SET, catalog, name), dependencies(catalog), dependents(catalog) { +} + +CatalogSet &DependencySetCatalogEntry::Dependencies() { + return dependencies; +} + +CatalogSet &DependencySetCatalogEntry::Dependents() { + return dependents; +} + +DependencySetCatalogEntry::~DependencySetCatalogEntry() { +} + +} // namespace duckdb diff --git a/src/catalog/dependency_manager.cpp b/src/catalog/dependency_manager.cpp index 901604a5fd71..e13d5f676a50 100644 --- a/src/catalog/dependency_manager.cpp +++ b/src/catalog/dependency_manager.cpp @@ -8,13 +8,57 @@ #include "duckdb/parser/expression/constant_expression.hpp" #include "duckdb/catalog/mapping_value.hpp" #include "duckdb/catalog/dependency_list.hpp" +#include "duckdb/common/enums/catalog_type.hpp" +#include "duckdb/catalog/catalog_entry/dependency_set_catalog_entry.hpp" namespace duckdb { -DependencyManager::DependencyManager(DuckCatalog &catalog) : catalog(catalog) { +DependencyManager::DependencyManager(DuckCatalog &catalog) : catalog(catalog), connections(catalog) { +} + +static string GetSchema(CatalogEntry &entry) { + if (entry.type == CatalogType::SCHEMA_ENTRY) { + return entry.name; + } + return entry.ParentSchema().name; +} + +static string GetMangledName(CatalogEntry &entry) { + auto schema = GetSchema(entry); + return StringUtil::Format("%s\0%s\0%s", CatalogTypeToString(entry.type), schema, entry.name); +} + +DependencySetCatalogEntry &DependencyManager::GetDependencySet(CatalogTransaction transaction, CatalogEntry &object) { + auto name = GetMangledName(object); + auto connection_p = connections.GetEntry(transaction, name); + if (!connection_p) { + auto new_connection = make_uniq(catalog, name); + auto &connection = *new_connection; + DependencyList empty_dependencies; + auto res = connections.CreateEntry(transaction, name, std::move(new_connection), empty_dependencies); + (void)res; + D_ASSERT(res); + return connection; + } + D_ASSERT(connection_p->type == CatalogType::DEPENDENCY_SET); + return connection_p->Cast(); +} + +CatalogSet &DependencyManager::GetDependenciesOfObject(CatalogTransaction transaction, CatalogEntry &object) { + auto &set = GetDependencySet(transaction, object); + return set. +} + +bool DependencyManager::IsDependencyEntry(CatalogEntry &entry) const { + return entry.type == CatalogType::DEPENDENCY_SET || entry.type == CatalogType::DEPENDENCY_ENTRY; } void DependencyManager::AddObject(CatalogTransaction transaction, CatalogEntry &object, DependencyList &dependencies) { + if (IsDependencyEntry(object)) { + // Don't do anything for this + return; + } + // check for each object in the sources if they were not deleted yet for (auto &dep : dependencies.set) { auto &dependency = dep.get(); @@ -32,6 +76,8 @@ void DependencyManager::AddObject(CatalogTransaction transaction, CatalogEntry & throw InternalException("Dependency has already been deleted?"); } } + auto &mappings = GetDependencyMappings(transaction, object); + // indexes do not require CASCADE to be dropped, they are simply always dropped along with the table auto dependency_type = object.type == CatalogType::INDEX_ENTRY ? DependencyType::DEPENDENCY_AUTOMATIC : DependencyType::DEPENDENCY_REGULAR; @@ -46,6 +92,10 @@ void DependencyManager::AddObject(CatalogTransaction transaction, CatalogEntry & } void DependencyManager::DropObject(CatalogTransaction transaction, CatalogEntry &object, bool cascade) { + if (IsDependencyEntry(object)) { + // Don't do anything for this + return; + } D_ASSERT(dependents_map.find(object) != dependents_map.end()); // first check the objects that depend on this object @@ -78,6 +128,12 @@ void DependencyManager::DropObject(CatalogTransaction transaction, CatalogEntry } void DependencyManager::AlterObject(CatalogTransaction transaction, CatalogEntry &old_obj, CatalogEntry &new_obj) { + if (IsDependencyEntry(new_obj)) { + D_ASSERT(IsDependencyEntry(old_obj)); + // Don't do anything for this + return; + } + D_ASSERT(dependents_map.find(old_obj) != dependents_map.end()); D_ASSERT(dependencies_map.find(old_obj) != dependencies_map.end()); @@ -124,11 +180,18 @@ void DependencyManager::AlterObject(CatalogTransaction transaction, CatalogEntry } void DependencyManager::EraseObject(CatalogEntry &object) { + if (IsDependencyEntry(object)) { + // Don't do anything for this + return; + } + // obtain the writing lock EraseObjectInternal(object); } void DependencyManager::EraseObjectInternal(CatalogEntry &object) { + D_ASSERT(!IsDependencyEntry(object)); + if (dependents_map.find(object) == dependents_map.end()) { // dependencies already removed return; @@ -158,6 +221,9 @@ void DependencyManager::Scan(const std::function write_lock(catalog.GetWriteLock()); diff --git a/src/include/duckdb/catalog/catalog_entry/dependency_catalog_entry.hpp b/src/include/duckdb/catalog/catalog_entry/dependency_catalog_entry.hpp new file mode 100644 index 000000000000..865b75701f22 --- /dev/null +++ b/src/include/duckdb/catalog/catalog_entry/dependency_catalog_entry.hpp @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/catalog_entry.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/common.hpp" +#include "duckdb/common/enums/catalog_type.hpp" +#include "duckdb/common/exception.hpp" +#include "duckdb/common/atomic.hpp" +#include "duckdb/common/optional_ptr.hpp" +#include "duckdb/catalog/catalog_entry.hpp" +#include "duckdb/catalog/catalog_set.hpp" +#include + +namespace duckdb { + +//! Resembles a connection between an object and the CatalogEntry that can be retrieved from the Catalog using the +//! identifiers listed here +class DependencyCatalogEntry : public InCatalogEntry { +public: + DependencyCatalogEntry(Catalog &catalog, const string &name); + ~DependencyCatalogEntry() override; + +private: + string name; + string schema; + CatalogType type; + // DependencyType dependency_type; +}; + +} // namespace duckdb diff --git a/src/include/duckdb/catalog/catalog_entry/dependency_set_catalog_entry.hpp b/src/include/duckdb/catalog/catalog_entry/dependency_set_catalog_entry.hpp new file mode 100644 index 000000000000..7fa440376c5a --- /dev/null +++ b/src/include/duckdb/catalog/catalog_entry/dependency_set_catalog_entry.hpp @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/catalog_entry.hpp +// +// +//===----------------------------------------------------------------------===// + +#pragma once + +#include "duckdb/common/common.hpp" +#include "duckdb/common/enums/catalog_type.hpp" +#include "duckdb/common/exception.hpp" +#include "duckdb/common/atomic.hpp" +#include "duckdb/common/optional_ptr.hpp" +#include "duckdb/catalog/catalog_entry.hpp" +#include "duckdb/catalog/catalog_set.hpp" +#include + +namespace duckdb { + +class DependencySetCatalogEntry : public InCatalogEntry { +public: + DependencySetCatalogEntry(Catalog &catalog, const string &name); + ~DependencySetCatalogEntry() override; + +public: + CatalogSet &Dependencies(); + CatalogSet &Dependents(); + +private: + string name; + CatalogSet dependencies; + CatalogSet dependents; +}; + +} // namespace duckdb diff --git a/src/include/duckdb/catalog/dependency_manager.hpp b/src/include/duckdb/catalog/dependency_manager.hpp index 3ebab885f7f6..75fe94942976 100644 --- a/src/include/duckdb/catalog/dependency_manager.hpp +++ b/src/include/duckdb/catalog/dependency_manager.hpp @@ -13,6 +13,7 @@ #include "duckdb/catalog/dependency.hpp" #include "duckdb/catalog/catalog_entry_map.hpp" #include "duckdb/catalog/catalog_transaction.hpp" +#include "duckdb/catalog/catalog_entry/dependency_set_catalog_entry.hpp" #include @@ -44,6 +45,13 @@ class DependencyManager { //! Map of objects that the source object DEPENDS on, i.e. when any of the entries in the vector perform a CASCADE //! drop then [object] is deleted as well catalog_entry_map_t dependencies_map; + CatalogSet connections; + +private: + bool IsDependencyEntry(CatalogEntry &entry) const; + DependencySetCatalogEntry &GetDependencySet(CatalogTransaction transaction, CatalogEntry &entry); + CatalogSet &GetDependenciesOfObject(CatalogTransaction, CatalogEntry &object); + CatalogSet &GetEntriesThatDependOnObject(CatalogTransaction, CatalogEntry &object); private: void AddObject(CatalogTransaction transaction, CatalogEntry &object, DependencyList &dependencies); diff --git a/src/include/duckdb/common/enums/catalog_type.hpp b/src/include/duckdb/common/enums/catalog_type.hpp index 2b9faa9ca410..cdba979a92f4 100644 --- a/src/include/duckdb/common/enums/catalog_type.hpp +++ b/src/include/duckdb/common/enums/catalog_type.hpp @@ -39,6 +39,10 @@ enum class CatalogType : uint8_t { // version info UPDATED_ENTRY = 50, DELETED_ENTRY = 51, + + // dependency info + DEPENDENCY_SET = 100, + DEPENDENCY_ENTRY = 101 }; DUCKDB_API string CatalogTypeToString(CatalogType type);