Add API for executing a query

This commit is contained in:
Josip Mrden 2024-02-28 13:07:59 +01:00
parent b6a55e534b
commit 8ba1f160d4
8 changed files with 76 additions and 3 deletions

View File

@ -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

View File

@ -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

View File

@ -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<Parameter> &parameters,

View File

@ -72,6 +72,12 @@ inline std::vector<storage::LabelId> NamesToLabels(const std::vector<std::string
return labels;
}
struct UserExecutionContextInfo {
enum class UserMode { NONE, USER, ROLE };
UserMode mode;
std::string name;
};
struct ExecutionContext {
DbAccessor *db_accessor{nullptr};
SymbolTable symbol_table;
@ -86,6 +92,7 @@ struct ExecutionContext {
TriggerContextCollector *trigger_context_collector{nullptr};
FrameChangeCollector *frame_change_collector{nullptr};
std::shared_ptr<utils::AsyncTimer> timer;
UserExecutionContextInfo user_info;
#ifdef MG_ENTERPRISE
std::unique_ptr<FineGrainedAuthChecker> auth_checker{nullptr};
#endif

View File

@ -1720,6 +1720,13 @@ PullPlan::PullPlan(const std::shared_ptr<PlanWrapper> 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

View File

@ -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

View File

@ -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);
});
}

View File

@ -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;
};