diff --git a/src/include/main/database_manager.h b/src/include/main/database_manager.h index 01cbd3eb2..7d589d405 100644 --- a/src/include/main/database_manager.h +++ b/src/include/main/database_manager.h @@ -33,11 +33,9 @@ class DatabaseManager { void loadGraphsFromCatalog(storage::MemoryManager* memoryManager, main::ClientContext* clientContext); void setDefaultGraph(const std::string& graphName); - void clearDefaultGraph(); bool hasGraph(const std::string& graphName); - catalog::Catalog* getGraphCatalog(const std::string& graphName); catalog::Catalog* getDefaultGraphCatalog() const; - bool hasDefaultGraph() const { return defaultGraph != "" && defaultGraph != "main"; } + bool hasDefaultGraph() const { return defaultGraph != ""; } std::string getDefaultGraphName() const { return defaultGraph; } std::vector getGraphs() const; storage::StorageManager* getDefaultGraphStorageManager() const; diff --git a/src/main/database_manager.cpp b/src/main/database_manager.cpp index ed107fea3..9f5b92d79 100644 --- a/src/main/database_manager.cpp +++ b/src/main/database_manager.cpp @@ -111,6 +111,11 @@ void DatabaseManager::createGraph(const std::string& graphName, storage::MemoryManager* memoryManager, main::ClientContext* clientContext, bool isAnyGraph) { auto upperCaseName = StringUtils::getUpper(graphName); + // main is the default graph + if (upperCaseName == "MAIN") { + throw RuntimeException{"MAIN is a reserved graph name."}; + } + // Check if graph already exists in system catalog auto mainCatalog = clientContext->getDatabase()->getCatalog(); auto transaction = TransactionContext::Get(*clientContext)->getActiveTransaction(); @@ -196,9 +201,6 @@ void DatabaseManager::createGraph(const std::string& graphName, } graphs.push_back(std::move(catalog)); - if (defaultGraph == "") { - defaultGraph = graphName; - } } void DatabaseManager::dropGraph(const std::string& graphName, main::ClientContext* clientContext) { @@ -259,10 +261,12 @@ void DatabaseManager::dropGraph(const std::string& graphName, main::ClientContex void DatabaseManager::setDefaultGraph(const std::string& graphName) { auto upperCaseName = StringUtils::getUpper(graphName); + if (upperCaseName == "MAIN") { - defaultGraph = "main"; + defaultGraph = ""; return; } + for (auto& graph : graphs) { auto graphNameUpper = StringUtils::getUpper(graph->getCatalogName()); if (graphNameUpper == upperCaseName) { @@ -273,10 +277,6 @@ void DatabaseManager::setDefaultGraph(const std::string& graphName) { throw BinderException{std::format("No graph named {}.", graphName)}; } -void DatabaseManager::clearDefaultGraph() { - defaultGraph = "main"; -} - void DatabaseManager::loadGraphsFromCatalog(storage::MemoryManager* memoryManager, main::ClientContext* clientContext) { auto mainCatalog = clientContext->getDatabase()->getCatalog(); @@ -322,11 +322,6 @@ void DatabaseManager::loadGraphsFromCatalog(storage::MemoryManager* memoryManage catalog->setStorageManager(std::move(storageManager)); graphs.push_back(std::move(catalog)); - - // Set first loaded graph as default if no default set - if (defaultGraph == "") { - defaultGraph = graphName; - } } } @@ -341,19 +336,8 @@ bool DatabaseManager::hasGraph(const std::string& graphName) { return false; } -catalog::Catalog* DatabaseManager::getGraphCatalog(const std::string& graphName) { - auto upperCaseName = StringUtils::getUpper(graphName); - for (auto& graph : graphs) { - auto graphNameUpper = StringUtils::getUpper(graph->getCatalogName()); - if (graphNameUpper == upperCaseName) { - return graph.get(); - } - } - throw BinderException{std::format("No graph named {}.", graphName)}; -} - catalog::Catalog* DatabaseManager::getDefaultGraphCatalog() const { - if (defaultGraph == "" || defaultGraph == "main") { + if (defaultGraph == "") { return nullptr; } auto upperCaseName = StringUtils::getUpper(defaultGraph); diff --git a/src/processor/operator/ddl/drop.cpp b/src/processor/operator/ddl/drop.cpp index daf99ea25..d668ca2fd 100644 --- a/src/processor/operator/ddl/drop.cpp +++ b/src/processor/operator/ddl/drop.cpp @@ -124,6 +124,11 @@ void Drop::dropGraph(const main::ClientContext* context) { auto dbManager = main::DatabaseManager::Get(*context); auto memoryManager = storage::MemoryManager::Get(*context); + // Protect the main graph unconditionally — IF EXISTS cannot bypass this. + if (StringUtils::getUpper(dropInfo.name) == "MAIN") { + throw BinderException("Cannot drop the main graph."); + } + if (!dbManager->hasGraph(dropInfo.name)) { auto message = std::format("Graph {} does not exist.", dropInfo.name); switch (dropInfo.conflictAction) { @@ -139,11 +144,6 @@ void Drop::dropGraph(const main::ClientContext* context) { } } - if (dbManager->hasDefaultGraph() && StringUtils::getUpper(dbManager->getDefaultGraphName()) == - StringUtils::getUpper(dropInfo.name)) { - dbManager->clearDefaultGraph(); - } - dbManager->dropGraph(dropInfo.name, const_cast(context)); appendMessage(std::format("Graph {} has been dropped.", dropInfo.name), memoryManager); } diff --git a/test/test_files/graph/any_graph.test b/test/test_files/graph/any_graph.test index 79b76d10c..62a45b1ed 100644 --- a/test/test_files/graph/any_graph.test +++ b/test/test_files/graph/any_graph.test @@ -33,3 +33,20 @@ _nodes -STATEMENT DROP GRAPH mygraph ---- ok + +-CASE AnyGraphNamedMain + +-LOG CreateAnyGraphNamedMain +-STATEMENT CREATE GRAPH main ANY +---- error +Runtime exception: MAIN is a reserved graph name. + +-LOG CreateAnyGraphNamedMainUpperCase +-STATEMENT CREATE GRAPH MAIN ANY +---- error +Runtime exception: MAIN is a reserved graph name. + +-LOG CreateAnyGraphNamedMainMixedCase +-STATEMENT CREATE GRAPH Main ANY +---- error +Runtime exception: MAIN is a reserved graph name. diff --git a/test/test_files/graph/graph.test b/test/test_files/graph/graph.test index 34a139095..8a139653d 100644 --- a/test/test_files/graph/graph.test +++ b/test/test_files/graph/graph.test @@ -125,6 +125,51 @@ person|foo1(graph) -STATEMENT DROP GRAPH foo1 ---- ok +-CASE MainGraphProtection + +-LOG CreateGraphNamedMain +-STATEMENT CREATE GRAPH main +---- error +Runtime exception: MAIN is a reserved graph name. + +-LOG CreateGraphNamedMainUpperCase +-STATEMENT CREATE GRAPH MAIN +---- error +Runtime exception: MAIN is a reserved graph name. + +-LOG CreateGraphNamedMainMixedCase +-STATEMENT CREATE GRAPH Main +---- error +Runtime exception: MAIN is a reserved graph name. + +-LOG DropGraphMain +-STATEMENT DROP GRAPH main +---- error +Binder exception: Cannot drop the main graph. + +-LOG DropGraphMainUpperCase +-STATEMENT DROP GRAPH MAIN +---- error +Binder exception: Cannot drop the main graph. + +-LOG DropGraphMainMixedCase +-STATEMENT DROP GRAPH Main +---- error +Binder exception: Cannot drop the main graph. + +-LOG DropGraphIfExistsMain +-STATEMENT DROP GRAPH IF EXISTS main +---- error +Binder exception: Cannot drop the main graph. + +-LOG UseGraphMain +-STATEMENT USE GRAPH main +---- ok + +-LOG UseGraphMainUpperCase +-STATEMENT USE GRAPH MAIN +---- ok + -CASE ErrorCases -LOG DuplicateGraphError -STATEMENT CREATE GRAPH graph1_ec