From 8ba1f160d458a44104c7aaf19faf8db4c3d566ef Mon Sep 17 00:00:00 2001 From: Josip Mrden Date: Wed, 28 Feb 2024 13:07:59 +0100 Subject: [PATCH] Add API for executing a query --- include/_mgp.hpp | 2 ++ include/mg_procedure.h | 5 ++++- include/mgp.hpp | 16 +++++++++++++- src/query/context.hpp | 7 ++++++ src/query/interpreter.cpp | 7 ++++++ src/query/interpreter_context.hpp | 6 +++++ src/query/procedure/mg_procedure_impl.cpp | 27 +++++++++++++++++++++++ src/query/procedure/mg_procedure_impl.hpp | 9 +++++++- 8 files changed, 76 insertions(+), 3 deletions(-) diff --git a/include/_mgp.hpp b/include/_mgp.hpp index 8b67bc36a..3091eac8e 100644 --- a/include/_mgp.hpp +++ b/include/_mgp.hpp @@ -851,4 +851,6 @@ inline void func_result_set_value(mgp_func_result *res, mgp_value *value, mgp_me MgInvokeVoid(mgp_func_result_set_value, res, value, memory); } +inline void execute_query(mgp_graph *graph, const char *query) { MgInvokeVoid(mgp_execute_query, graph, query); } + } // namespace mgp diff --git a/include/mg_procedure.h b/include/mg_procedure.h index 93ef241d8..1b8641fb1 100644 --- a/include/mg_procedure.h +++ b/include/mg_procedure.h @@ -1,4 +1,4 @@ -// Copyright 2023 Memgraph Ltd. +// Copyright 2024 Memgraph Ltd. // // Use of this software is governed by the Business Source License // included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source @@ -1800,6 +1800,9 @@ enum mgp_error mgp_func_result_set_error_msg(struct mgp_func_result *result, con /// mgp_func_result. enum mgp_error mgp_func_result_set_value(struct mgp_func_result *result, struct mgp_value *value, struct mgp_memory *memory); + +enum mgp_error mgp_execute_query(mgp_graph *graph, const char *query); + /// @} #ifdef __cplusplus diff --git a/include/mgp.hpp b/include/mgp.hpp index 3f7ed591e..b8adb2ea3 100644 --- a/include/mgp.hpp +++ b/include/mgp.hpp @@ -1,4 +1,4 @@ -// Copyright 2023 Memgraph Ltd. +// Copyright 2024 Memgraph Ltd. // // Use of this software is governed by the Business Source License // included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source @@ -93,6 +93,7 @@ class Relationship; struct MapItem; class Duration; class Value; +class QueryExecution; struct StealType {}; inline constexpr StealType steal{}; @@ -1550,6 +1551,15 @@ class Return { mgp_type *GetMGPType() const; }; +class QueryExecution { + public: + QueryExecution(mgp_graph *graph); + void ExecuteQuery(std::string_view query); + + private: + mgp_graph *graph_; +}; + enum class ProcedureType : uint8_t { Read, Write, @@ -4286,6 +4296,10 @@ inline mgp_type *Return::GetMGPType() const { return util::ToMGPType(type_); } +inline QueryExecution::QueryExecution(mgp_graph *graph) : graph_(graph) {} + +inline void QueryExecution::ExecuteQuery(std::string_view query) const { mgp::execute_query(graph_, query.data()); } + // do not enter namespace detail { inline void AddParamsReturnsToProc(mgp_proc *proc, std::vector ¶meters, diff --git a/src/query/context.hpp b/src/query/context.hpp index f1522053c..288505c7d 100644 --- a/src/query/context.hpp +++ b/src/query/context.hpp @@ -72,6 +72,12 @@ inline std::vector NamesToLabels(const std::vector timer; + UserExecutionContextInfo user_info; #ifdef MG_ENTERPRISE std::unique_ptr auth_checker{nullptr}; #endif diff --git a/src/query/interpreter.cpp b/src/query/interpreter.cpp index 0cc0f182a..4395da387 100644 --- a/src/query/interpreter.cpp +++ b/src/query/interpreter.cpp @@ -1720,6 +1720,13 @@ PullPlan::PullPlan(const std::shared_ptr plan, const Parameters &pa ctx_.evaluation_context.parameters = parameters; ctx_.evaluation_context.properties = NamesToProperties(plan->ast_storage().properties_, dba); ctx_.evaluation_context.labels = NamesToLabels(plan->ast_storage().labels_, dba); + if (!user_or_role) { + ctx_.user_info = {.mode = UserExecutionContextInfo::UserMode::NONE, .name = ""}; + } else { + ctx_.user_info = {.mode = user_or_role->username() ? UserExecutionContextInfo::UserMode::USER + : UserExecutionContextInfo::UserMode::ROLE, + .name = user_or_role->key()}; + } #ifdef MG_ENTERPRISE if (license::global_license_checker.IsEnterpriseValidFast() && user_or_role && *user_or_role && dba) { // Create only if an explicit user is defined diff --git a/src/query/interpreter_context.hpp b/src/query/interpreter_context.hpp index 1124ab3fd..1849431f5 100644 --- a/src/query/interpreter_context.hpp +++ b/src/query/interpreter_context.hpp @@ -27,6 +27,7 @@ #include "storage/v2/transaction.hpp" #include "system/state.hpp" #include "system/system.hpp" +#include "utils/exceptions.hpp" #include "utils/gatekeeper.hpp" #include "utils/skip_list.hpp" #include "utils/spin_lock.hpp" @@ -56,6 +57,11 @@ struct QueryUserOrRole; struct InterpreterContext { static InterpreterContext *instance; + static InterpreterContext *getInstance() { + MG_ASSERT(instance == nullptr, "Interpreter context has not been initialized!"); + return instance; + } + static InterpreterContext *getInstance(InterpreterConfig interpreter_config, dbms::DbmsHandler *dbms_handler, replication::ReplicationState *rs, memgraph::system::System &system, #ifdef MG_ENTERPRISE diff --git a/src/query/procedure/mg_procedure_impl.cpp b/src/query/procedure/mg_procedure_impl.cpp index d6ce3c7b7..4b2d8d1c6 100644 --- a/src/query/procedure/mg_procedure_impl.cpp +++ b/src/query/procedure/mg_procedure_impl.cpp @@ -27,7 +27,10 @@ #include "mg_procedure.h" #include "module.hpp" #include "query/db_accessor.hpp" +#include "query/discard_value_stream.hpp" #include "query/frontend/ast/ast.hpp" +#include "query/interpreter.hpp" +#include "query/interpreter_context.hpp" #include "query/procedure/cypher_types.hpp" #include "query/procedure/fmt.hpp" #include "query/procedure/mg_procedure_helpers.hpp" @@ -4021,3 +4024,27 @@ mgp_error mgp_untrack_current_thread_allocations(mgp_graph *graph) { std::visit([](auto *db_accessor) -> void { db_accessor->UntrackCurrentThreadAllocations(); }, graph->impl); }); } + +mgp_error mgp_execute_query(mgp_graph *graph, const char *query) { + return WrapExceptions([&]() { + auto query_string = std::string(query); + auto user_info = graph->ctx->user_info; + auto *instance = memgraph::query::InterpreterContext::getInstance(); + + memgraph::query::Interpreter interpreter(instance); + + instance->interpreters.WithLock([&interpreter](auto &interpreters) { interpreters.insert(&interpreter); }); + + memgraph::utils::OnScopeExit erase_interpreter([&] { + instance->interpreters.WithLock([&interpreter](auto &interpreters) { interpreters.erase(&interpreter); }); + }); + + memgraph::query::AllowEverythingAuthChecker tmp_auth_checker; + auto tmp_user = tmp_auth_checker.GenQueryUser(std::nullopt, std::nullopt); + interpreter.SetUser(tmp_user); + + auto results = interpreter.Prepare(query_string, {}, {}); + memgraph::query::DiscardValueResultStream stream; + interpreter.Pull(&stream, {}, results.qid); + }); +} diff --git a/src/query/procedure/mg_procedure_impl.hpp b/src/query/procedure/mg_procedure_impl.hpp index 17cac4eca..e3af8b863 100644 --- a/src/query/procedure/mg_procedure_impl.hpp +++ b/src/query/procedure/mg_procedure_impl.hpp @@ -1,4 +1,4 @@ -// Copyright 2023 Memgraph Ltd. +// Copyright 2024 Memgraph Ltd. // // Use of this software is governed by the Business Source License // included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source @@ -24,6 +24,7 @@ #include "query/context.hpp" #include "query/db_accessor.hpp" #include "query/frontend/ast/ast.hpp" + #include "query/procedure/cypher_type_ptr.hpp" #include "query/typed_value.hpp" #include "storage/v2/view.hpp" @@ -993,3 +994,9 @@ struct mgp_messages { bool ContainsDeleted(const mgp_value *val); memgraph::query::TypedValue ToTypedValue(const mgp_value &val, memgraph::utils::MemoryResource *memory); + +struct mgp_query_execution { + explicit mgp_query_execution(){}; + + ~mgp_query_execution() = default; +};