From 1145ea87ad1a74fb9e0b516ee89161c291519867 Mon Sep 17 00:00:00 2001 From: Josip Mrden Date: Wed, 28 Feb 2024 23:23:15 +0100 Subject: [PATCH] Add support for headers --- include/_mgp.hpp | 16 ++++-- include/mg_procedure.h | 16 +++--- include/mgp.hpp | 24 +++++++-- src/query/procedure/mg_procedure_impl.cpp | 61 +++++++++++++++-------- src/query/procedure/mg_procedure_impl.hpp | 23 +++++---- 5 files changed, 97 insertions(+), 43 deletions(-) diff --git a/include/_mgp.hpp b/include/_mgp.hpp index 5e566cd63..c4facc2f1 100644 --- a/include/_mgp.hpp +++ b/include/_mgp.hpp @@ -851,12 +851,20 @@ 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 mgp_query_execution_result *execute_query(mgp_graph *graph, const char *query, mgp_memory *memory) { - return MgInvoke(mgp_execute_query, graph, memory, query); +inline mgp_execution_result *execute_query(mgp_graph *graph, const char *query, mgp_memory *memory) { + return MgInvoke(mgp_execute_query, graph, memory, query); } -inline std::vector get_query_execution_headers(mgp_query_execution_result *query_execution) { - return MgInvoke>(mgp_get_query_execution_headers, query_execution); +inline mgp_execution_headers *mgp_fetch_execution_headers(mgp_execution_result *exec_result) { + return MgInvoke(mgp_fetch_execution_headers, exec_result); +} + +inline size_t execution_headers_size(mgp_execution_headers *headers) { + return MgInvoke(mgp_execution_headers_size, headers); +} + +inline const char *execution_headers_at(mgp_execution_headers *headers, size_t index) { + return MgInvoke(mgp_execution_headers_at, headers, index); } } // namespace mgp diff --git a/include/mg_procedure.h b/include/mg_procedure.h index 40682aab5..b1766105d 100644 --- a/include/mg_procedure.h +++ b/include/mg_procedure.h @@ -1801,15 +1801,19 @@ 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); -struct mgp_query_execution_result; +struct mgp_execution_headers; -enum mgp_error mgp_execute_query(mgp_graph *graph, struct mgp_memory *memory, const char *query, - struct mgp_query_execution_result **result); +enum mgp_error mgp_execution_headers_at(struct mgp_execution_headers *headers, size_t index, const char **result); -struct mgp_query_execution_headers; +enum mgp_error mgp_execution_headers_size(struct mgp_execution_headers *headers, size_t *result); -enum mgp_error mgp_get_query_execution_headers(struct mgp_query_execution_result *query_execution, - struct mgp_query_execution_headers **result); +struct mgp_execution_result; + +enum mgp_error mgp_execute_query(struct mgp_graph *graph, struct mgp_memory *memory, const char *query, + struct mgp_execution_result **result); + +enum mgp_error mgp_fetch_execution_headers(struct mgp_execution_result *exec_result, + struct mgp_execution_headers **headers); /// @} diff --git a/include/mgp.hpp b/include/mgp.hpp index 0dae89e1b..29b4c35a9 100644 --- a/include/mgp.hpp +++ b/include/mgp.hpp @@ -1552,6 +1552,16 @@ class Return { mgp_type *GetMGPType() const; }; +class ExecutionHeaders { + public: + ExecutionHeaders(mgp_execution_headers *headers); + size_t Size() const; + std::string At(size_t index) const; + + private: + mgp_execution_headers *headers_; +}; + class QueryExecution { public: QueryExecution(mgp_graph *graph); @@ -1562,10 +1572,10 @@ class QueryExecution { }; class QueryExecutionResult { - mgp_query_execution_result *result_; + mgp_execution_result *result_; public: - QueryExecutionResult(mgp_query_execution_result *result); + QueryExecutionResult(mgp_execution_result *result); std::vector Headers() const; }; @@ -4305,13 +4315,21 @@ inline mgp_type *Return::GetMGPType() const { return util::ToMGPType(type_); } +inline ExecutionHeaders::ExecutionHeaders(mgp_execution_headers *headers) : headers_(headers) {} + +inline size_t ExecutionHeaders::Size() const { return mgp::execution_headers_size(headers_); } + +inline std::string ExecutionHeaders::At(size_t index) const { + return std::string(mgp::execution_headers_at(headers_, index)); +} + inline QueryExecution::QueryExecution(mgp_graph *graph) : graph_(graph) {} 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) {} +inline QueryExecutionResult::QueryExecutionResult(mgp_execution_result *result) : result_(result) {} inline std::vector QueryExecutionResult::Headers() const { return mgp::get_query_execution_headers(result_); diff --git a/src/query/procedure/mg_procedure_impl.cpp b/src/query/procedure/mg_procedure_impl.cpp index c899040a6..a5cbf0e3e 100644 --- a/src/query/procedure/mg_procedure_impl.cpp +++ b/src/query/procedure/mg_procedure_impl.cpp @@ -4025,13 +4025,6 @@ mgp_error mgp_untrack_current_thread_allocations(mgp_graph *graph) { }); } -struct MgProcedureResultStream final { - using Row = std::vector; - using Rows = std::vector; - Rows rows; - void Result(const Row &row) { rows.push_back(row); } -}; - std::vector> GetMgpRowsFromTypedValues( std::vector> tv_rows, mgp_graph *graph, mgp_memory *memory) { std::vector> mgp_rows; @@ -4046,17 +4039,41 @@ std::vector> GetMgpRowsFromTypedValues( return mgp_rows; } -mgp_query_execution_headers::mgp_query_execution_headers(std::vector headers) : headers(headers){}; +mgp_execution_headers::mgp_execution_headers(memgraph::utils::pmr::vector &&storage) + : headers(std::move(storage)){}; -mgp_query_execution_result::mgp_query_execution_result(std::vector headers, - std::vector> tv_rows, - mgp_graph *graph, mgp_memory *memory) - : headers(headers), rows(GetMgpRowsFromTypedValues(std::move(tv_rows), graph, memory)) {} +mgp_error mgp_execution_headers_size(mgp_execution_headers *headers, size_t *result) { + static_assert(noexcept(headers->headers.size())); + *result = headers->headers.size(); + return mgp_error::MGP_ERROR_NO_ERROR; +} -mgp_error mgp_execute_query(mgp_graph *graph, mgp_memory *memory, const char *query, - mgp_query_execution_result **result) { +mgp_error mgp_execution_headers_at(mgp_execution_headers *headers, size_t index, const char **result) { return WrapExceptions( - [&]() { + [headers, index] { + if (index >= Call(mgp_execution_headers_size, headers)) { + throw std::out_of_range("Header cannot be retrieved, because index exceeds headers' size!"); + } + return headers->headers[index].data(); + }, + result); +} + +mgp_execution_result::mgp_execution_result(mgp_execution_headers &&headers, + std::vector> tv_rows, + mgp_graph *graph, mgp_memory *memory) + : headers(std::move(headers)), rows(GetMgpRowsFromTypedValues(std::move(tv_rows), graph, memory)) {} + +struct MgProcedureResultStream final { + using Row = std::vector; + using Rows = std::vector; + Rows rows; + void Result(const Row &row) { rows.push_back(row); } +}; + +mgp_error mgp_execute_query(mgp_graph *graph, mgp_memory *memory, const char *query, mgp_execution_result **result) { + return WrapExceptions( + [query, graph, memory]() { auto query_string = std::string(query); auto *instance = memgraph::query::InterpreterContext::getInstance(); @@ -4073,13 +4090,17 @@ mgp_error mgp_execute_query(mgp_graph *graph, mgp_memory *memory, const char *qu MgProcedureResultStream stream; interpreter.Pull(&stream, {}, prepare_query_result.qid); - return NewRawMgpObject(memory, std::move(prepare_query_result.headers), - std::move(stream.rows), graph, memory); + memgraph::utils::pmr::vector headers(memory->impl); + for (auto header : prepare_query_result.headers) { + headers.emplace_back(header); + } + + return NewRawMgpObject(memory, mgp_execution_headers{std::move(headers)}, + std::move(stream.rows), graph, memory); }, result); } -mgp_error mgp_get_query_execution_headers(mgp_query_execution_result *execution_result, - mgp_query_execution_headers **result) { - return WrapExceptions([&]() { return &execution_result->headers; }, result); +mgp_error mgp_fetch_execution_headers(mgp_execution_result *exec_result, mgp_execution_headers **result) { + return WrapExceptions([exec_result]() { return &exec_result->headers; }, result); } diff --git a/src/query/procedure/mg_procedure_impl.hpp b/src/query/procedure/mg_procedure_impl.hpp index 50705351b..1a8bf425b 100644 --- a/src/query/procedure/mg_procedure_impl.hpp +++ b/src/query/procedure/mg_procedure_impl.hpp @@ -995,20 +995,23 @@ bool ContainsDeleted(const mgp_value *val); memgraph::query::TypedValue ToTypedValue(const mgp_value &val, memgraph::utils::MemoryResource *memory); -struct mgp_query_execution_headers { - explicit mgp_query_execution_headers(std::vector headers); - ~mgp_query_execution_headers() = default; +struct mgp_execution_headers { + using allocator_type = memgraph::utils::Allocator; + using storage_type = memgraph::utils::pmr::vector; + explicit mgp_execution_headers(storage_type &&storage); - std::vector headers; + ~mgp_execution_headers() = default; + + storage_type headers; }; -struct mgp_query_execution_result { - explicit mgp_query_execution_result(std::vector headers, - std::vector> tv_rows, mgp_graph *graph, - mgp_memory *memory); +struct mgp_execution_result { + explicit mgp_execution_result(mgp_execution_headers &&headers, + std::vector> tv_rows, mgp_graph *graph, + mgp_memory *memory); - ~mgp_query_execution_result() = default; + ~mgp_execution_result() = default; - mgp_query_execution_headers headers; + mgp_execution_headers headers; std::vector> rows; };