From 7deac4ac8b46343a9b06f915d25bd0e71c6a78b6 Mon Sep 17 00:00:00 2001 From: Antonio Andelic <antonio2368@users.noreply.github.com> Date: Thu, 13 Jan 2022 13:46:32 +0100 Subject: [PATCH] Extra procedures transformation info (#310) --- src/query/CMakeLists.txt | 1 + src/query/procedure/mg_procedure_helpers.cpp | 36 ++++ src/query/procedure/mg_procedure_helpers.hpp | 21 +++ src/query/procedure/module.cpp | 176 +++++++++++++------ src/query/procedure/module.hpp | 2 + src/query/stream/streams.cpp | 77 +++----- tests/unit/cypher_main_visitor.cpp | 5 +- 7 files changed, 207 insertions(+), 111 deletions(-) create mode 100644 src/query/procedure/mg_procedure_helpers.cpp diff --git a/src/query/CMakeLists.txt b/src/query/CMakeLists.txt index 68f78a85b..ef46e793d 100644 --- a/src/query/CMakeLists.txt +++ b/src/query/CMakeLists.txt @@ -30,6 +30,7 @@ set(mg_query_sources plan/rule_based_planner.cpp plan/variable_start_planner.cpp procedure/mg_procedure_impl.cpp + procedure/mg_procedure_helpers.cpp procedure/module.cpp procedure/py_module.cpp serialization/property_value.cpp diff --git a/src/query/procedure/mg_procedure_helpers.cpp b/src/query/procedure/mg_procedure_helpers.cpp new file mode 100644 index 000000000..550936347 --- /dev/null +++ b/src/query/procedure/mg_procedure_helpers.cpp @@ -0,0 +1,36 @@ +// Copyright 2021 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 +// License, and you may not use this file except in compliance with the Business Source License. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +#include "query/procedure/mg_procedure_helpers.hpp" + +namespace query::procedure { +MgpUniquePtr<mgp_value> GetStringValueOrSetError(const char *string, mgp_memory *memory, mgp_result *result) { + procedure::MgpUniquePtr<mgp_value> value{nullptr, mgp_value_destroy}; + const auto success = + TryOrSetError([&] { return procedure::CreateMgpObject(value, mgp_value_make_string, string, memory); }, result); + if (!success) { + value.reset(); + } + + return value; +} + +bool InsertResultOrSetError(mgp_result *result, mgp_result_record *record, const char *result_name, mgp_value *value) { + if (const auto err = mgp_result_record_insert(record, result_name, value); err != MGP_ERROR_NO_ERROR) { + const auto error_msg = fmt::format("Unable to set the result for {}, error = {}", result_name, err); + static_cast<void>(mgp_result_set_error_msg(result, error_msg.c_str())); + return false; + } + + return true; +} + +} // namespace query::procedure diff --git a/src/query/procedure/mg_procedure_helpers.hpp b/src/query/procedure/mg_procedure_helpers.hpp index c47b0d30f..60e1a15c5 100644 --- a/src/query/procedure/mg_procedure_helpers.hpp +++ b/src/query/procedure/mg_procedure_helpers.hpp @@ -15,6 +15,8 @@ #include <type_traits> #include <utility> +#include <fmt/format.h> + #include "mg_procedure.h" namespace query::procedure { @@ -45,4 +47,23 @@ mgp_error CreateMgpObject(MgpUniquePtr<TObj> &obj, TFunc func, TArgs &&...args) obj.reset(raw_obj); return err; } + +template <typename Fun> +[[nodiscard]] bool TryOrSetError(Fun &&func, mgp_result *result) { + if (const auto err = func(); err == MGP_ERROR_UNABLE_TO_ALLOCATE) { + static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!")); + return false; + } else if (err != MGP_ERROR_NO_ERROR) { + const auto error_msg = fmt::format("Unexpected error ({})!", err); + static_cast<void>(mgp_result_set_error_msg(result, error_msg.c_str())); + return false; + } + return true; +} + +[[nodiscard]] MgpUniquePtr<mgp_value> GetStringValueOrSetError(const char *string, mgp_memory *memory, + mgp_result *result); + +[[nodiscard]] bool InsertResultOrSetError(mgp_result *result, mgp_result_record *record, const char *result_name, + mgp_value *value); } // namespace query::procedure diff --git a/src/query/procedure/module.cpp b/src/query/procedure/module.cpp index 12f0a6c81..e322d9cee 100644 --- a/src/query/procedure/module.cpp +++ b/src/query/procedure/module.cpp @@ -18,7 +18,9 @@ extern "C" { #include <optional> -#include "fmt/format.h" +#include <fmt/format.h> +#include <unistd.h> + #include "py/py.hpp" #include "query/procedure/mg_procedure_helpers.hpp" #include "query/procedure/py_module.hpp" @@ -53,6 +55,8 @@ class BuiltinModule final : public Module { void AddTransformation(std::string_view name, mgp_trans trans); + std::optional<std::filesystem::path> Path() const override { return std::nullopt; } + private: /// Registered procedures std::map<std::string, mgp_proc, std::less<>> procedures_; @@ -133,6 +137,20 @@ void RegisterMgLoad(ModuleRegistry *module_registry, utils::RWLock *lock, Builti module->AddProcedure("load", std::move(load)); } +namespace { +[[nodiscard]] bool IsFileEditable(const std::optional<std::filesystem::path> &path) { + return path && access(path->c_str(), W_OK) == 0; +} + +std::string GetPathString(const std::optional<std::filesystem::path> &path) { + if (!path) { + return "builtin"; + } + + return std::filesystem::canonical(*path).generic_string(); +} +} // namespace + void RegisterMgProcedures( // We expect modules to be sorted by name. const std::map<std::string, std::unique_ptr<Module>, std::less<>> *all_modules, BuiltinModule *module) { @@ -147,57 +165,80 @@ void RegisterMgProcedures( static_assert( std::is_same_v<decltype(module->Procedures()), const std::map<std::string, mgp_proc, std::less<>> *>, "Expected module procedures to be sorted by name"); + + const auto path = module->Path(); + const auto path_string = GetPathString(path); + const auto is_editable = IsFileEditable(path); + for (const auto &[proc_name, proc] : *module->Procedures()) { mgp_result_record *record{nullptr}; - if (const auto err = mgp_result_new_record(result, &record); err == MGP_ERROR_UNABLE_TO_ALLOCATE) { - static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!")); - return; - } else if (err != MGP_ERROR_NO_ERROR) { - static_cast<void>(mgp_result_set_error_msg(result, "Unexpected error")); + { + const auto success = TryOrSetError([&] { return mgp_result_new_record(result, &record); }, result); + if (!success) { + return; + } + } + + const auto path_value = GetStringValueOrSetError(path_string.c_str(), memory, result); + if (!path_value) { return; } + MgpUniquePtr<mgp_value> is_editable_value{nullptr, mgp_value_destroy}; + { + const auto success = TryOrSetError( + [&] { return CreateMgpObject(is_editable_value, mgp_value_make_bool, is_editable, memory); }, result); + if (!success) { + return; + } + } + utils::pmr::string full_name(module_name, memory->impl); full_name.append(1, '.'); full_name.append(proc_name); - MgpUniquePtr<mgp_value> name_value{nullptr, mgp_value_destroy}; - if (const auto err = CreateMgpObject(name_value, mgp_value_make_string, full_name.c_str(), memory); - err == MGP_ERROR_UNABLE_TO_ALLOCATE) { - static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!")); - return; - } else if (err != MGP_ERROR_NO_ERROR) { - static_cast<void>(mgp_result_set_error_msg(result, "Unexpected error")); + const auto name_value = GetStringValueOrSetError(full_name.c_str(), memory, result); + if (!name_value) { return; } + std::stringstream ss; ss << module_name << "."; PrintProcSignature(proc, &ss); const auto signature = ss.str(); - MgpUniquePtr<mgp_value> signature_value{nullptr, mgp_value_destroy}; - if (const auto err = CreateMgpObject(signature_value, mgp_value_make_string, signature.c_str(), memory); - err == MGP_ERROR_UNABLE_TO_ALLOCATE) { - static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!")); - return; - } else if (err != MGP_ERROR_NO_ERROR) { - static_cast<void>(mgp_result_set_error_msg(result, "Unexpected error")); + const auto signature_value = GetStringValueOrSetError(signature.c_str(), memory, result); + if (!signature_value) { return; } - MgpUniquePtr<mgp_value> is_write_value{nullptr, mgp_value_destroy}; - if (const auto err = - CreateMgpObject(is_write_value, mgp_value_make_bool, proc.is_write_procedure ? 1 : 0, memory); - err == MGP_ERROR_UNABLE_TO_ALLOCATE) { - static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!")); - return; - } else if (err != MGP_ERROR_NO_ERROR) { - static_cast<void>(mgp_result_set_error_msg(result, "Unexpected error")); + MgpUniquePtr<mgp_value> is_write_value{nullptr, mgp_value_destroy}; + { + const auto success = TryOrSetError( + [&, &proc = proc] { + return CreateMgpObject(is_write_value, mgp_value_make_bool, proc.is_write_procedure ? 1 : 0, memory); + }, + result); + if (!success) { + return; + } + } + + if (!InsertResultOrSetError(result, record, "name", name_value.get())) { return; } - const auto err1 = mgp_result_record_insert(record, "name", name_value.get()); - const auto err2 = mgp_result_record_insert(record, "signature", signature_value.get()); - const auto err3 = mgp_result_record_insert(record, "is_write", is_write_value.get()); - if (err1 != MGP_ERROR_NO_ERROR || err2 != MGP_ERROR_NO_ERROR || err3 != MGP_ERROR_NO_ERROR) { - static_cast<void>(mgp_result_set_error_msg(result, "Unable to set the result!")); + + if (!InsertResultOrSetError(result, record, "signature", signature_value.get())) { + return; + } + + if (!InsertResultOrSetError(result, record, "is_write", is_write_value.get())) { + return; + } + + if (!InsertResultOrSetError(result, record, "path", path_value.get())) { + return; + } + + if (!InsertResultOrSetError(result, record, "is_editable", is_editable_value.get())) { return; } } @@ -207,6 +248,8 @@ void RegisterMgProcedures( MG_ASSERT(mgp_proc_add_result(&procedures, "name", Call<mgp_type *>(mgp_type_string)) == MGP_ERROR_NO_ERROR); MG_ASSERT(mgp_proc_add_result(&procedures, "signature", Call<mgp_type *>(mgp_type_string)) == MGP_ERROR_NO_ERROR); MG_ASSERT(mgp_proc_add_result(&procedures, "is_write", Call<mgp_type *>(mgp_type_bool)) == MGP_ERROR_NO_ERROR); + MG_ASSERT(mgp_proc_add_result(&procedures, "path", Call<mgp_type *>(mgp_type_string)) == MGP_ERROR_NO_ERROR); + MG_ASSERT(mgp_proc_add_result(&procedures, "is_editable", Call<mgp_type *>(mgp_type_bool)) == MGP_ERROR_NO_ERROR); module->AddProcedure("procedures", std::move(procedures)); } @@ -219,32 +262,52 @@ void RegisterMgTransformations(const std::map<std::string, std::unique_ptr<Modul static_assert( std::is_same_v<decltype(module->Transformations()), const std::map<std::string, mgp_trans, std::less<>> *>, "Expected module transformations to be sorted by name"); + + const auto path = module->Path(); + const auto path_string = GetPathString(path); + const auto is_editable = IsFileEditable(path); + for (const auto &[trans_name, proc] : *module->Transformations()) { mgp_result_record *record{nullptr}; - if (const auto err = mgp_result_new_record(result, &record); err == MGP_ERROR_UNABLE_TO_ALLOCATE) { - static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!")); - return; - } else if (err != MGP_ERROR_NO_ERROR) { - static_cast<void>(mgp_result_set_error_msg(result, "Unexpected error")); + { + const auto success = TryOrSetError([&] { return mgp_result_new_record(result, &record); }, result); + if (!success) { + return; + } + } + + const auto path_value = GetStringValueOrSetError(path_string.c_str(), memory, result); + if (!path_value) { return; } + MgpUniquePtr<mgp_value> is_editable_value{nullptr, mgp_value_destroy}; + { + const auto success = TryOrSetError( + [&] { return CreateMgpObject(is_editable_value, mgp_value_make_bool, is_editable, memory); }, result); + if (!success) { + return; + } + } + utils::pmr::string full_name(module_name, memory->impl); full_name.append(1, '.'); full_name.append(trans_name); - MgpUniquePtr<mgp_value> name_value{nullptr, mgp_value_destroy}; - if (const auto err = CreateMgpObject(name_value, mgp_value_make_string, full_name.c_str(), memory); - err == MGP_ERROR_UNABLE_TO_ALLOCATE) { - static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!")); - return; - } else if (err != MGP_ERROR_NO_ERROR) { - static_cast<void>(mgp_result_set_error_msg(result, "Unexpected error")); + const auto name_value = GetStringValueOrSetError(full_name.c_str(), memory, result); + if (!name_value) { return; } - if (const auto err = mgp_result_record_insert(record, "name", name_value.get()); err != MGP_ERROR_NO_ERROR) { - static_cast<void>(mgp_result_set_error_msg(result, "Unable to set the result!")); + if (!InsertResultOrSetError(result, record, "name", name_value.get())) { + return; + } + + if (!InsertResultOrSetError(result, record, "path", path_value.get())) { + return; + } + + if (!InsertResultOrSetError(result, record, "is_editable", is_editable_value.get())) { return; } } @@ -252,6 +315,8 @@ void RegisterMgTransformations(const std::map<std::string, std::unique_ptr<Modul }; mgp_proc procedures("transformations", transformations_cb, utils::NewDeleteResource(), false); MG_ASSERT(mgp_proc_add_result(&procedures, "name", Call<mgp_type *>(mgp_type_string)) == MGP_ERROR_NO_ERROR); + MG_ASSERT(mgp_proc_add_result(&procedures, "path", Call<mgp_type *>(mgp_type_string)) == MGP_ERROR_NO_ERROR); + MG_ASSERT(mgp_proc_add_result(&procedures, "is_editable", Call<mgp_type *>(mgp_type_bool)) == MGP_ERROR_NO_ERROR); module->AddProcedure("transformations", std::move(procedures)); } @@ -297,6 +362,8 @@ class SharedLibraryModule final : public Module { const std::map<std::string, mgp_trans, std::less<>> *Transformations() const override; + std::optional<std::filesystem::path> Path() const override { return file_path_; } + private: /// Path as requested for loading the module from a library. std::filesystem::path file_path_; @@ -424,6 +491,7 @@ class PythonModule final : public Module { const std::map<std::string, mgp_proc, std::less<>> *Procedures() const override; const std::map<std::string, mgp_trans, std::less<>> *Transformations() const override; + std::optional<std::filesystem::path> Path() const override { return file_path_; } private: std::filesystem::path file_path_; @@ -677,9 +745,9 @@ template <typename T> concept ModuleProperties = utils::SameAsAnyOf<T, mgp_proc, mgp_trans>; template <ModuleProperties T> -std::optional<std::pair<procedure::ModulePtr, const T *>> MakePairIfPropFound(const ModuleRegistry &module_registry, - std::string_view fully_qualified_name, - utils::MemoryResource *memory) { +std::optional<std::pair<ModulePtr, const T *>> MakePairIfPropFound(const ModuleRegistry &module_registry, + std::string_view fully_qualified_name, + utils::MemoryResource *memory) { auto prop_fun = [](auto &module) { if constexpr (std::is_same_v<T, mgp_proc>) { return module->Procedures(); @@ -700,13 +768,13 @@ std::optional<std::pair<procedure::ModulePtr, const T *>> MakePairIfPropFound(co } // namespace -std::optional<std::pair<procedure::ModulePtr, const mgp_proc *>> FindProcedure( - const ModuleRegistry &module_registry, std::string_view fully_qualified_procedure_name, - utils::MemoryResource *memory) { +std::optional<std::pair<ModulePtr, const mgp_proc *>> FindProcedure(const ModuleRegistry &module_registry, + std::string_view fully_qualified_procedure_name, + utils::MemoryResource *memory) { return MakePairIfPropFound<mgp_proc>(module_registry, fully_qualified_procedure_name, memory); } -std::optional<std::pair<procedure::ModulePtr, const mgp_trans *>> FindTransformation( +std::optional<std::pair<ModulePtr, const mgp_trans *>> FindTransformation( const ModuleRegistry &module_registry, std::string_view fully_qualified_transformation_name, utils::MemoryResource *memory) { return MakePairIfPropFound<mgp_trans>(module_registry, fully_qualified_transformation_name, memory); diff --git a/src/query/procedure/module.hpp b/src/query/procedure/module.hpp index 469738ec2..cefdbc780 100644 --- a/src/query/procedure/module.hpp +++ b/src/query/procedure/module.hpp @@ -45,6 +45,8 @@ class Module { virtual const std::map<std::string, mgp_proc, std::less<>> *Procedures() const = 0; /// Returns registered transformations of this module virtual const std::map<std::string, mgp_trans, std::less<>> *Transformations() const = 0; + + virtual std::optional<std::filesystem::path> Path() const = 0; }; /// Proxy for a registered Module, acquires a read lock from ModuleRegistry. diff --git a/src/query/stream/streams.cpp b/src/query/stream/streams.cpp index a80fa5478..f8d28ffe2 100644 --- a/src/query/stream/streams.cpp +++ b/src/query/stream/streams.cpp @@ -158,43 +158,6 @@ void from_json(const nlohmann::json &data, StreamStatus<TStream> &status) { from_json(data, status.info); } -namespace { -template <typename Fun> -[[nodiscard]] bool TryOrSetError(Fun &&func, mgp_result *result) { - if (const auto err = func(); err == MGP_ERROR_UNABLE_TO_ALLOCATE) { - static_cast<void>(mgp_result_set_error_msg(result, "Not enough memory!")); - return false; - } else if (err != MGP_ERROR_NO_ERROR) { - const auto error_msg = fmt::format("Unexpected error ({})!", err); - static_cast<void>(mgp_result_set_error_msg(result, error_msg.c_str())); - return false; - } - return true; -} - -[[nodiscard]] auto GetStringValueOrSetError(const char *string, mgp_memory *memory, mgp_result *result) { - procedure::MgpUniquePtr<mgp_value> value{nullptr, mgp_value_destroy}; - const auto success = - TryOrSetError([&] { return procedure::CreateMgpObject(value, mgp_value_make_string, string, memory); }, result); - if (!success) { - value.reset(); - } - - return value; -} - -[[nodiscard]] bool InsertResultOrSetError(mgp_result *result, mgp_result_record *record, const auto *result_name, - mgp_value *value) { - if (const auto err = mgp_result_record_insert(record, result_name, value); err != MGP_ERROR_NO_ERROR) { - const auto error_msg = fmt::format("Unable to set the result for {}, error = {}", result_name, err); - static_cast<void>(mgp_result_set_error_msg(result, error_msg.c_str())); - return false; - } - - return true; -} -} // namespace - Streams::Streams(InterpreterContext *interpreter_context, std::filesystem::path directory) : interpreter_context_(interpreter_context), storage_(std::move(directory)) { RegisterProcedures(); @@ -260,20 +223,22 @@ void Streams::RegisterKafkaProcedures() { const auto info = stream_source_ptr->Info(kafka_stream.transformation_name); mgp_result_record *record{nullptr}; { - const auto success = TryOrSetError([&] { return mgp_result_new_record(result, &record); }, result); + const auto success = + procedure::TryOrSetError([&] { return mgp_result_new_record(result, &record); }, result); if (!success) { return; } } - const auto consumer_group_value = GetStringValueOrSetError(info.consumer_group.c_str(), memory, result); + const auto consumer_group_value = + procedure::GetStringValueOrSetError(info.consumer_group.c_str(), memory, result); if (!consumer_group_value) { return; } procedure::MgpUniquePtr<mgp_list> topic_names{nullptr, mgp_list_destroy}; { - const auto success = TryOrSetError( + const auto success = procedure::TryOrSetError( [&] { return procedure::CreateMgpObject(topic_names, mgp_list_make_empty, info.topics.size(), memory); }, @@ -284,7 +249,7 @@ void Streams::RegisterKafkaProcedures() { } for (const auto &topic : info.topics) { - auto topic_value = GetStringValueOrSetError(topic.c_str(), memory, result); + auto topic_value = procedure::GetStringValueOrSetError(topic.c_str(), memory, result); if (!topic_value) { return; } @@ -293,7 +258,7 @@ void Streams::RegisterKafkaProcedures() { procedure::MgpUniquePtr<mgp_value> topics_value{nullptr, mgp_value_destroy}; { - const auto success = TryOrSetError( + const auto success = procedure::TryOrSetError( [&] { return procedure::CreateMgpObject(topics_value, mgp_value_make_list, topic_names.release()); }, @@ -304,22 +269,22 @@ void Streams::RegisterKafkaProcedures() { } const auto bootstrap_servers_value = - GetStringValueOrSetError(info.bootstrap_servers.c_str(), memory, result); + procedure::GetStringValueOrSetError(info.bootstrap_servers.c_str(), memory, result); if (!bootstrap_servers_value) { return; } - if (!InsertResultOrSetError(result, record, consumer_group_result_name.data(), - consumer_group_value.get())) { + if (!procedure::InsertResultOrSetError(result, record, consumer_group_result_name.data(), + consumer_group_value.get())) { return; } - if (!InsertResultOrSetError(result, record, topics_result_name.data(), topics_value.get())) { + if (!procedure::InsertResultOrSetError(result, record, topics_result_name.data(), topics_value.get())) { return; } - if (!InsertResultOrSetError(result, record, bootstrap_servers_result_name.data(), - bootstrap_servers_value.get())) { + if (!procedure::InsertResultOrSetError(result, record, bootstrap_servers_result_name.data(), + bootstrap_servers_value.get())) { return; } }, @@ -363,20 +328,21 @@ void Streams::RegisterPulsarProcedures() { const auto info = stream_source_ptr->Info(pulsar_stream.transformation_name); mgp_result_record *record{nullptr}; { - const auto success = TryOrSetError([&] { return mgp_result_new_record(result, &record); }, result); + const auto success = + procedure::TryOrSetError([&] { return mgp_result_new_record(result, &record); }, result); if (!success) { return; } } - auto service_url_value = GetStringValueOrSetError(info.service_url.c_str(), memory, result); + auto service_url_value = procedure::GetStringValueOrSetError(info.service_url.c_str(), memory, result); if (!service_url_value) { return; } procedure::MgpUniquePtr<mgp_list> topic_names{nullptr, mgp_list_destroy}; { - const auto success = TryOrSetError( + const auto success = procedure::TryOrSetError( [&] { return procedure::CreateMgpObject(topic_names, mgp_list_make_empty, info.topics.size(), memory); }, @@ -387,7 +353,7 @@ void Streams::RegisterPulsarProcedures() { } for (const auto &topic : info.topics) { - auto topic_value = GetStringValueOrSetError(topic.c_str(), memory, result); + auto topic_value = procedure::GetStringValueOrSetError(topic.c_str(), memory, result); if (!topic_value) { return; } @@ -396,7 +362,7 @@ void Streams::RegisterPulsarProcedures() { procedure::MgpUniquePtr<mgp_value> topics_value{nullptr, mgp_value_destroy}; { - const auto success = TryOrSetError( + const auto success = procedure::TryOrSetError( [&] { return procedure::CreateMgpObject(topics_value, mgp_value_make_list, topic_names.release()); }, @@ -406,11 +372,12 @@ void Streams::RegisterPulsarProcedures() { } } - if (!InsertResultOrSetError(result, record, topics_result_name.data(), topics_value.get())) { + if (!procedure::InsertResultOrSetError(result, record, topics_result_name.data(), topics_value.get())) { return; } - if (!InsertResultOrSetError(result, record, service_url_result_name.data(), service_url_value.get())) { + if (!procedure::InsertResultOrSetError(result, record, service_url_result_name.data(), + service_url_value.get())) { return; } }, diff --git a/tests/unit/cypher_main_visitor.cpp b/tests/unit/cypher_main_visitor.cpp index c40e75e0a..8eb548243 100644 --- a/tests/unit/cypher_main_visitor.cpp +++ b/tests/unit/cypher_main_visitor.cpp @@ -206,6 +206,7 @@ class MockModule : public procedure::Module { const std::map<std::string, mgp_proc, std::less<>> *Procedures() const override { return &procedures; } const std::map<std::string, mgp_trans, std::less<>> *Transformations() const override { return &transformations; } + std::optional<std::filesystem::path> Path() const override { return std::nullopt; }; std::map<std::string, mgp_proc, std::less<>> procedures{}; std::map<std::string, mgp_trans, std::less<>> transformations{}; @@ -2812,7 +2813,7 @@ TEST_P(CypherMainVisitorTest, CallProcedureYieldAsterisk) { ASSERT_TRUE(identifier->user_declared_); identifier_names.push_back(identifier->name_); } - ASSERT_THAT(identifier_names, UnorderedElementsAre("name", "signature", "is_write")); + ASSERT_THAT(identifier_names, UnorderedElementsAre("name", "signature", "is_write", "path", "is_editable")); ASSERT_EQ(identifier_names, call_proc->result_fields_); CheckCallProcedureDefaultMemoryLimit(ast_generator, *call_proc); } @@ -2837,7 +2838,7 @@ TEST_P(CypherMainVisitorTest, CallProcedureYieldAsteriskReturnAsterisk) { ASSERT_TRUE(identifier->user_declared_); identifier_names.push_back(identifier->name_); } - ASSERT_THAT(identifier_names, UnorderedElementsAre("name", "signature", "is_write")); + ASSERT_THAT(identifier_names, UnorderedElementsAre("name", "signature", "is_write", "path", "is_editable")); ASSERT_EQ(identifier_names, call_proc->result_fields_); CheckCallProcedureDefaultMemoryLimit(ast_generator, *call_proc); }