Skip to content

Commit

Permalink
create catalog entries for dependency management
Browse files Browse the repository at this point in the history
  • Loading branch information
Tishj committed Oct 26, 2023
1 parent 9e78949 commit 84b079e
Show file tree
Hide file tree
Showing 8 changed files with 186 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/catalog/catalog_entry/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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} $<TARGET_OBJECTS:duckdb_catalog_entries>
Expand Down
12 changes: 12 additions & 0 deletions src/catalog/catalog_entry/dependency_catalog_entry.cpp
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions src/catalog/catalog_entry/dependency_set_catalog_entry.cpp
Original file line number Diff line number Diff line change
@@ -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
68 changes: 67 additions & 1 deletion src/catalog/dependency_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<DependencySetCatalogEntry>(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<DependencySetCatalogEntry>();
}

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();
Expand All @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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());

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -158,6 +221,9 @@ void DependencyManager::Scan(const std::function<void(CatalogEntry &, CatalogEnt
}

void DependencyManager::AddOwnership(CatalogTransaction transaction, CatalogEntry &owner, CatalogEntry &entry) {
D_ASSERT(!IsDependencyEntry(entry));
D_ASSERT(!IsDependencyEntry(owner));

// lock the catalog for writing
lock_guard<mutex> write_lock(catalog.GetWriteLock());

Expand Down
Original file line number Diff line number Diff line change
@@ -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 <memory>

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
Original file line number Diff line number Diff line change
@@ -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 <memory>

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
8 changes: 8 additions & 0 deletions src/include/duckdb/catalog/dependency_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <functional>

Expand Down Expand Up @@ -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<catalog_entry_set_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);
Expand Down
4 changes: 4 additions & 0 deletions src/include/duckdb/common/enums/catalog_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 84b079e

Please sign in to comment.