From 2c0fc680de893b58814b77b07e9463e7a78a0829 Mon Sep 17 00:00:00 2001 From: Josip Mrden Date: Wed, 28 Feb 2024 14:56:38 +0100 Subject: [PATCH] Created query execution result --- include/_mgp.hpp | 4 +- include/mg_procedure.h | 5 +- include/mgp.hpp | 16 +++++- src/query/procedure/mg_procedure_impl.cpp | 63 +++++++++++++++++------ src/query/procedure/mg_procedure_impl.hpp | 9 ++-- 5 files changed, 73 insertions(+), 24 deletions(-) diff --git a/include/_mgp.hpp b/include/_mgp.hpp index 3091eac8e..9bd954202 100644 --- a/include/_mgp.hpp +++ b/include/_mgp.hpp @@ -851,6 +851,8 @@ 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); } +inline void execute_query(mgp_graph *graph, const char *query, mgp_memory *memory) { + MgInvokeVoid(mgp_execute_query, graph, memory, query); +} } // namespace mgp diff --git a/include/mg_procedure.h b/include/mg_procedure.h index 1b8641fb1..aead32b96 100644 --- a/include/mg_procedure.h +++ b/include/mg_procedure.h @@ -1801,7 +1801,10 @@ enum mgp_error mgp_func_result_set_error_msg(struct mgp_func_result *result, con 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); +struct mgp_query_execution_result; + +enum mgp_error mgp_execute_query(mgp_graph *graph, struct mgp_memory *memory, const char *query, + struct mgp_query_execution_result **result); /// @} diff --git a/include/mgp.hpp b/include/mgp.hpp index c22c982db..33110b523 100644 --- a/include/mgp.hpp +++ b/include/mgp.hpp @@ -94,6 +94,7 @@ struct MapItem; class Duration; class Value; class QueryExecution; +class QueryExecutionResult; struct StealType {}; inline constexpr StealType steal{}; @@ -1554,12 +1555,19 @@ class Return { class QueryExecution { public: QueryExecution(mgp_graph *graph); - void ExecuteQuery(std::string_view query) const; + QueryExecutionResult ExecuteQuery(std::string_view query) const; private: mgp_graph *graph_; }; +class QueryExecutionResult { + mgp_query_execution_result *result_; + + public: + QueryExecutionResult(mgp_query_execution_result *result); +}; + enum class ProcedureType : uint8_t { Read, Write, @@ -4298,7 +4306,11 @@ inline mgp_type *Return::GetMGPType() const { inline QueryExecution::QueryExecution(mgp_graph *graph) : graph_(graph) {} -inline void QueryExecution::ExecuteQuery(std::string_view query) const { mgp::execute_query(graph_, query.data()); } +inline QueryExecutionResult QueryExecution::ExecuteQuery(std::string_view query) const { + mgp::MemHandlerCallback(execute_query, graph_, query.data()); +} + +inline QueryExecutionResult::QueryExecutionResult(mgp_query_execution_result *result) : result_(result) {} // do not enter namespace detail { diff --git a/src/query/procedure/mg_procedure_impl.cpp b/src/query/procedure/mg_procedure_impl.cpp index 373099a40..909951249 100644 --- a/src/query/procedure/mg_procedure_impl.cpp +++ b/src/query/procedure/mg_procedure_impl.cpp @@ -28,7 +28,6 @@ #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" @@ -4026,22 +4025,52 @@ mgp_error mgp_untrack_current_thread_allocations(mgp_graph *graph) { }); } -mgp_error mgp_execute_query(mgp_graph *graph, const char *query) { - return WrapExceptions([&]() { - auto query_string = std::string(query); - auto *instance = memgraph::query::InterpreterContext::getInstance(); +struct MgProcedureResultStream final { + using Row = std::vector; + using Rows = std::vector; + Rows rows; + void Result(const Row &row) { rows.push_back(row); } +}; - memgraph::query::Interpreter interpreter(instance); - interpreter.SetUser(graph->ctx->user_or_role); +std::vector> GetMgpRowsFromTypedValues( + std::vector> tv_rows, mgp_graph *graph, mgp_memory *memory) { + std::vector> mgp_rows; + for (auto &row : tv_rows) { + std::vector vals; + for (auto &val : row) { + vals.emplace_back(val, graph, memory->impl); + } + mgp_rows.emplace_back(std::move(vals)); + } - instance->interpreters.WithLock([&interpreter](auto &interpreters) { interpreters.insert(&interpreter); }); - - memgraph::utils::OnScopeExit erase_interpreter([&] { - instance->interpreters.WithLock([&interpreter](auto &interpreters) { interpreters.erase(&interpreter); }); - }); - - auto results = interpreter.Prepare(query_string, {}, {}); - memgraph::query::DiscardValueResultStream stream; - interpreter.Pull(&stream, {}, results.qid); - }); + return mgp_rows; +} + +mgp_query_execution_result::mgp_query_execution_result(std::vector> tv_rows, + mgp_graph *graph, mgp_memory *memory) + : rows(GetMgpRowsFromTypedValues(std::move(tv_rows), graph, memory)) {} + +mgp_error mgp_execute_query(mgp_graph *graph, mgp_memory *memory, const char *query, + mgp_query_execution_result **result) { + return WrapExceptions( + [&]() { + auto query_string = std::string(query); + auto *instance = memgraph::query::InterpreterContext::getInstance(); + + memgraph::query::Interpreter interpreter(instance); + interpreter.SetUser(graph->ctx->user_or_role); + + instance->interpreters.WithLock([&interpreter](auto &interpreters) { interpreters.insert(&interpreter); }); + + memgraph::utils::OnScopeExit erase_interpreter([&] { + instance->interpreters.WithLock([&interpreter](auto &interpreters) { interpreters.erase(&interpreter); }); + }); + + auto results = interpreter.Prepare(query_string, {}, {}); + MgProcedureResultStream stream; + interpreter.Pull(&stream, {}, results.qid); + + return NewRawMgpObject(memory, std::move(stream.rows), graph, memory); + }, + result); } diff --git a/src/query/procedure/mg_procedure_impl.hpp b/src/query/procedure/mg_procedure_impl.hpp index e3af8b863..3569d0406 100644 --- a/src/query/procedure/mg_procedure_impl.hpp +++ b/src/query/procedure/mg_procedure_impl.hpp @@ -995,8 +995,11 @@ 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(){}; +struct mgp_query_execution_result { + explicit mgp_query_execution_result(std::vector> tv_rows, mgp_graph *graph, + mgp_memory *memory); - ~mgp_query_execution() = default; + ~mgp_query_execution_result() = default; + + std::vector> rows; };