From c4d9116c9ccac4715bd42ec057c9f2030a302819 Mon Sep 17 00:00:00 2001 From: gvolfing <gabor.volfinger@memgraph.io> Date: Tue, 7 Nov 2023 09:35:28 +0100 Subject: [PATCH] Add queries to obtain the labels and edge types Add two queries to be able to retrieve the labels and edge types this is done through additions to the DatabaseInfoQuery query types. --- src/query/frontend/ast/ast.hpp | 2 +- .../frontend/ast/cypher_main_visitor.cpp | 8 +++++ .../frontend/opencypher/grammar/Cypher.g4 | 6 +++- .../opencypher/grammar/MemgraphCypher.g4 | 1 + .../opencypher/grammar/MemgraphCypherLexer.g4 | 1 + .../frontend/semantic/required_privileges.cpp | 3 ++ src/query/interpreter.cpp | 32 +++++++++++++++++++ 7 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/query/frontend/ast/ast.hpp b/src/query/frontend/ast/ast.hpp index 6b7fdb2c6..0b7061a4e 100644 --- a/src/query/frontend/ast/ast.hpp +++ b/src/query/frontend/ast/ast.hpp @@ -2932,7 +2932,7 @@ class DatabaseInfoQuery : public memgraph::query::Query { static const utils::TypeInfo kType; const utils::TypeInfo &GetTypeInfo() const override { return kType; } - enum class InfoType { INDEX, CONSTRAINT }; + enum class InfoType { INDEX, CONSTRAINT, EDGE_TYPES, NODE_LABELS }; DEFVISITABLE(QueryVisitor<void>); diff --git a/src/query/frontend/ast/cypher_main_visitor.cpp b/src/query/frontend/ast/cypher_main_visitor.cpp index 6b75061fb..a1a94a9c3 100644 --- a/src/query/frontend/ast/cypher_main_visitor.cpp +++ b/src/query/frontend/ast/cypher_main_visitor.cpp @@ -124,6 +124,14 @@ antlrcpp::Any CypherMainVisitor::visitDatabaseInfoQuery(MemgraphCypher::Database info_query->info_type_ = DatabaseInfoQuery::InfoType::CONSTRAINT; return info_query; } + if (ctx->edgetypeInfo()) { + info_query->info_type_ = DatabaseInfoQuery::InfoType::EDGE_TYPES; + return info_query; + } + if (ctx->nodelabelInfo()) { + info_query->info_type_ = DatabaseInfoQuery::InfoType::NODE_LABELS; + return info_query; + } // Should never get here throw utils::NotYetImplemented("Database info query: '{}'", ctx->getText()); } diff --git a/src/query/frontend/opencypher/grammar/Cypher.g4 b/src/query/frontend/opencypher/grammar/Cypher.g4 index 53f1fc765..8dfde7c21 100644 --- a/src/query/frontend/opencypher/grammar/Cypher.g4 +++ b/src/query/frontend/opencypher/grammar/Cypher.g4 @@ -47,9 +47,13 @@ indexInfo : INDEX INFO ; constraintInfo : CONSTRAINT INFO ; +edgetypeInfo : EDGE_TYPES INFO ; + +nodelabelInfo : NODE_LABELS INFO ; + buildInfo : BUILD INFO ; -databaseInfoQuery : SHOW ( indexInfo | constraintInfo ) ; +databaseInfoQuery : SHOW ( indexInfo | constraintInfo | edgetypeInfo | nodelabelInfo ) ; systemInfoQuery : SHOW ( storageInfo | buildInfo ) ; diff --git a/src/query/frontend/opencypher/grammar/MemgraphCypher.g4 b/src/query/frontend/opencypher/grammar/MemgraphCypher.g4 index bac189a53..d585acbb1 100644 --- a/src/query/frontend/opencypher/grammar/MemgraphCypher.g4 +++ b/src/query/frontend/opencypher/grammar/MemgraphCypher.g4 @@ -61,6 +61,7 @@ memgraphCypherKeyword : cypherKeyword | GRANT | HEADER | IDENTIFIED + | NODE_LABELS | NULLIF | IMPORT | INACTIVE diff --git a/src/query/frontend/opencypher/grammar/MemgraphCypherLexer.g4 b/src/query/frontend/opencypher/grammar/MemgraphCypherLexer.g4 index db1a1ae76..1b44a6e79 100644 --- a/src/query/frontend/opencypher/grammar/MemgraphCypherLexer.g4 +++ b/src/query/frontend/opencypher/grammar/MemgraphCypherLexer.g4 @@ -89,6 +89,7 @@ MULTI_DATABASE_EDIT : M U L T I UNDERSCORE D A T A B A S E UNDERSCORE E D I MULTI_DATABASE_USE : M U L T I UNDERSCORE D A T A B A S E UNDERSCORE U S E ; NEXT : N E X T ; NO : N O ; +NODE_LABELS : N O D E UNDERSCORE L A B E L S ; NOTHING : N O T H I N G ; ON_DISK_TRANSACTIONAL : O N UNDERSCORE D I S K UNDERSCORE T R A N S A C T I O N A L ; NULLIF : N U L L I F ; diff --git a/src/query/frontend/semantic/required_privileges.cpp b/src/query/frontend/semantic/required_privileges.cpp index b5b75e26e..04772cded 100644 --- a/src/query/frontend/semantic/required_privileges.cpp +++ b/src/query/frontend/semantic/required_privileges.cpp @@ -38,6 +38,9 @@ class PrivilegeExtractor : public QueryVisitor<void>, public HierarchicalTreeVis void Visit(DatabaseInfoQuery &info_query) override { switch (info_query.info_type_) { case DatabaseInfoQuery::InfoType::INDEX: + // TODO: Reconsider priviliges, this 4 should have the same. + case DatabaseInfoQuery::InfoType::EDGE_TYPES: + case DatabaseInfoQuery::InfoType::NODE_LABELS: // TODO: This should be INDEX | STATS, but we don't have support for // *or* with privileges. AddPrivilege(AuthQuery::Privilege::INDEX); diff --git a/src/query/interpreter.cpp b/src/query/interpreter.cpp index 074c90176..9313f4547 100644 --- a/src/query/interpreter.cpp +++ b/src/query/interpreter.cpp @@ -3076,6 +3076,38 @@ PreparedQuery PrepareDatabaseInfoQuery(ParsedQuery parsed_query, bool in_explici }; break; } + case DatabaseInfoQuery::InfoType::EDGE_TYPES: { + header = {"edge types"}; + handler = [storage = current_db.db_acc_->get()->storage(), dba] { + auto edge_types = dba->ListAllPossiblyPresentEdgeTypes(); + std::vector<std::vector<TypedValue>> results; + results.reserve(edge_types.size()); + for (auto &edge_type : edge_types) { + results.push_back({TypedValue(edge_type)}); + } + + return std::pair{results, QueryHandlerResult::COMMIT}; + }; + + break; + } + case DatabaseInfoQuery::InfoType::NODE_LABELS: { + header = {"node labels"}; + handler = [storage = current_db.db_acc_->get()->storage(), dba] { + auto node_labels = dba->ListAllPossiblyPresentVertexLabels(); + std::vector<std::vector<TypedValue>> results; + results.reserve(node_labels.size()); + for (auto &node_label : node_labels) { + results.push_back({TypedValue(node_label)}); + } + + return std::pair{results, QueryHandlerResult::COMMIT}; + }; + + break; + } + + // NODE_LABELS } return PreparedQuery{std::move(header), std::move(parsed_query.required_privileges),