From a878a11e70d22e8d48d2f4b2682bebfdb96ffa78 Mon Sep 17 00:00:00 2001 From: Teon Banek Date: Mon, 26 Aug 2019 15:50:26 +0200 Subject: [PATCH] Add FunctionContext to simplify awesome function signature Reviewers: ipaljak, mferencevic Reviewed By: mferencevic Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D2327 --- src/query/frontend/ast/ast.lcp | 7 +- .../interpret/awesome_memgraph_functions.cpp | 213 ++++++++---------- .../interpret/awesome_memgraph_functions.hpp | 24 +- src/query/interpret/eval.hpp | 6 +- 4 files changed, 123 insertions(+), 127 deletions(-) diff --git a/src/query/frontend/ast/ast.lcp b/src/query/frontend/ast/ast.lcp index f684cf855..5d73fa209 100644 --- a/src/query/frontend/ast/ast.lcp +++ b/src/query/frontend/ast/ast.lcp @@ -12,10 +12,6 @@ #include "storage/common/types/property_value.hpp" #include "utils/typeinfo.hpp" -namespace database { -class GraphDbAccessor; -} - cpp<# (lcp:namespace query) @@ -788,7 +784,8 @@ cpp<# :slk-save #'slk-save-ast-vector :slk-load (slk-load-ast-vector "Expression")) (function-name "std::string" :scope :public) - (function "std::function" + (function "std::function" :scope :public :dont-save t :clone :copy diff --git a/src/query/interpret/awesome_memgraph_functions.cpp b/src/query/interpret/awesome_memgraph_functions.cpp index 1714789ac..45f5fa637 100644 --- a/src/query/interpret/awesome_memgraph_functions.cpp +++ b/src/query/interpret/awesome_memgraph_functions.cpp @@ -7,9 +7,9 @@ #include #include -#include "database/single_node/dump.hpp" -#include "query/context.hpp" +#include "database/graph_db_accessor.hpp" #include "query/exceptions.hpp" +#include "query/typed_value.hpp" #include "utils/string.hpp" namespace query { @@ -332,21 +332,15 @@ void FType(const char *name, const TypedValue *args, int64_t nargs, // TODO: Implement degrees, haversin, radians // TODO: Implement spatial functions -/////////////////////////// IMPORTANT NOTE! //////////////////////////////////// -// All of the functions take mutable `TypedValue *` to arguments, but none of -// the functions should ever need to actually modify the arguments! Let's try to -// keep our sanity in a good state by treating the arguments as immutable. -//////////////////////////////////////////////////////////////////////////////// - -TypedValue EndNode(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, database::GraphDbAccessor *) { +TypedValue EndNode(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("endNode", args, nargs); if (args[0].IsNull()) return TypedValue(ctx.memory); return TypedValue(args[0].ValueEdge().to(), ctx.memory); } -TypedValue Head(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Head(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("head", args, nargs); if (args[0].IsNull()) return TypedValue(ctx.memory); const auto &list = args[0].ValueList(); @@ -354,8 +348,8 @@ TypedValue Head(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, return TypedValue(list[0], ctx.memory); } -TypedValue Last(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Last(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("last", args, nargs); if (args[0].IsNull()) return TypedValue(ctx.memory); const auto &list = args[0].ValueList(); @@ -363,10 +357,10 @@ TypedValue Last(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, return TypedValue(list.back(), ctx.memory); } -TypedValue Properties(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, - database::GraphDbAccessor *dba) { +TypedValue Properties(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("properties", args, nargs); + auto *dba = ctx.db_accessor; auto get_properties = [&](const auto &record_accessor) { TypedValue::TMap properties(ctx.memory); for (const auto &property : record_accessor.Properties()) { @@ -387,8 +381,8 @@ TypedValue Properties(TypedValue *args, int64_t nargs, } } -TypedValue Size(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Size(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("size", args, nargs); switch (args[0].type()) { case TypedValue::Type::Null: @@ -413,16 +407,15 @@ TypedValue Size(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, } } -TypedValue StartNode(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue StartNode(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("startNode", args, nargs); if (args[0].IsNull()) return TypedValue(ctx.memory); return TypedValue(args[0].ValueEdge().from(), ctx.memory); } -TypedValue Degree(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Degree(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("degree", args, nargs); if (args[0].IsNull()) return TypedValue(ctx.memory); const auto &vertex = args[0].ValueVertex(); @@ -431,26 +424,24 @@ TypedValue Degree(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, ctx.memory); } -TypedValue InDegree(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, database::GraphDbAccessor *) { +TypedValue InDegree(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("inDegree", args, nargs); if (args[0].IsNull()) return TypedValue(ctx.memory); const auto &vertex = args[0].ValueVertex(); return TypedValue(static_cast(vertex.in_degree()), ctx.memory); } -TypedValue OutDegree(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue OutDegree(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("outDegree", args, nargs); if (args[0].IsNull()) return TypedValue(ctx.memory); const auto &vertex = args[0].ValueVertex(); return TypedValue(static_cast(vertex.out_degree()), ctx.memory); } -TypedValue ToBoolean(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue ToBoolean(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("toBoolean", args, nargs); switch (args[0].type()) { case TypedValue::Type::Null: @@ -473,15 +464,14 @@ TypedValue ToBoolean(TypedValue *args, int64_t nargs, } } -TypedValue ToFloat(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, database::GraphDbAccessor *) { +TypedValue ToFloat(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("toFloat", args, nargs); switch (args[0].type()) { case TypedValue::Type::Null: return TypedValue(ctx.memory); case TypedValue::Type::Int: - return TypedValue(static_cast(args[0].ValueInt()), - ctx.memory); + return TypedValue(static_cast(args[0].ValueInt()), ctx.memory); case TypedValue::Type::Double: return TypedValue(args[0], ctx.memory); case TypedValue::Type::String: @@ -497,9 +487,8 @@ TypedValue ToFloat(TypedValue *args, int64_t nargs, } } -TypedValue ToInteger(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue ToInteger(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("toInteger", args, nargs); switch (args[0].type()) { case TypedValue::Type::Null: @@ -527,17 +516,19 @@ TypedValue ToInteger(TypedValue *args, int64_t nargs, } } -TypedValue Type(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *dba) { +TypedValue Type(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("type", args, nargs); + auto *dba = ctx.db_accessor; if (args[0].IsNull()) return TypedValue(ctx.memory); return TypedValue(dba->EdgeTypeName(args[0].ValueEdge().EdgeType()), ctx.memory); } -TypedValue Keys(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *dba) { +TypedValue Keys(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("keys", args, nargs); + auto *dba = ctx.db_accessor; auto get_keys = [&](const auto &record_accessor) { TypedValue::TVector keys(ctx.memory); for (const auto &property : record_accessor.Properties()) { @@ -557,9 +548,10 @@ TypedValue Keys(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, } } -TypedValue Labels(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *dba) { +TypedValue Labels(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("labels", args, nargs); + auto *dba = ctx.db_accessor; if (args[0].IsNull()) return TypedValue(ctx.memory); TypedValue::TVector labels(ctx.memory); for (const auto &label : args[0].ValueVertex().labels()) { @@ -568,8 +560,8 @@ TypedValue Labels(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, return TypedValue(std::move(labels)); } -TypedValue Nodes(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Nodes(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("nodes", args, nargs); if (args[0].IsNull()) return TypedValue(ctx.memory); const auto &vertices = args[0].ValuePath().vertices(); @@ -579,9 +571,8 @@ TypedValue Nodes(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, return TypedValue(std::move(values)); } -TypedValue Relationships(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Relationships(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("relationships", args, nargs); if (args[0].IsNull()) return TypedValue(ctx.memory); const auto &edges = args[0].ValuePath().edges(); @@ -591,8 +582,8 @@ TypedValue Relationships(TypedValue *args, int64_t nargs, return TypedValue(std::move(values)); } -TypedValue Range(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Range(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType, Or, Optional>>("range", args, nargs); for (int64_t i = 0; i < nargs; ++i) @@ -613,8 +604,8 @@ TypedValue Range(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, return TypedValue(std::move(list)); } -TypedValue Tail(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Tail(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("tail", args, nargs); if (args[0].IsNull()) return TypedValue(ctx.memory); TypedValue::TVector list(args[0].ValueList(), ctx.memory); @@ -623,9 +614,8 @@ TypedValue Tail(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, return TypedValue(std::move(list)); } -TypedValue UniformSample(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue UniformSample(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType, Or>("uniformSample", args, nargs); static thread_local std::mt19937 pseudo_rand_gen_{std::random_device{}()}; @@ -643,8 +633,8 @@ TypedValue UniformSample(TypedValue *args, int64_t nargs, return TypedValue(std::move(sampled)); } -TypedValue Abs(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Abs(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("abs", args, nargs); switch (args[0].type()) { case TypedValue::Type::Null: @@ -659,8 +649,8 @@ TypedValue Abs(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, } #define WRAP_CMATH_FLOAT_FUNCTION(name, lowercased_name) \ - TypedValue name(TypedValue *args, int64_t nargs, \ - const EvaluationContext &ctx, database::GraphDbAccessor *) { \ + TypedValue name(const TypedValue *args, int64_t nargs, \ + const FunctionContext &ctx) { \ FType>(#lowercased_name, args, nargs); \ switch (args[0].type()) { \ case TypedValue::Type::Null: \ @@ -693,8 +683,8 @@ WRAP_CMATH_FLOAT_FUNCTION(Tan, tan) #undef WRAP_CMATH_FLOAT_FUNCTION -TypedValue Atan2(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Atan2(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType, Or>("atan2", args, nargs); if (args[0].type() == TypedValue::Type::Null) return TypedValue(ctx.memory); if (args[1].type() == TypedValue::Type::Null) return TypedValue(ctx.memory); @@ -713,8 +703,8 @@ TypedValue Atan2(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, return TypedValue(atan2(y, x), ctx.memory); } -TypedValue Sign(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Sign(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("sign", args, nargs); auto sign = [&](auto x) { return TypedValue((0 < x) - (x < 0), ctx.memory); }; switch (args[0].type()) { @@ -729,20 +719,20 @@ TypedValue Sign(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, } } -TypedValue E(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue E(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType("e", args, nargs); return TypedValue(M_E, ctx.memory); } -TypedValue Pi(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Pi(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType("pi", args, nargs); return TypedValue(M_PI, ctx.memory); } -TypedValue Rand(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Rand(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType("rand", args, nargs); static thread_local std::mt19937 pseudo_rand_gen_{std::random_device{}()}; static thread_local std::uniform_real_distribution<> rand_dist_{0, 1}; @@ -750,9 +740,8 @@ TypedValue Rand(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, } template -TypedValue StringMatchOperator(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue StringMatchOperator(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType, Or>(TPredicate::name, args, nargs); if (args[0].IsNull() || args[1].IsNull()) return TypedValue(ctx.memory); const auto &s1 = args[0].ValueString(); @@ -793,8 +782,8 @@ struct ContainsPredicate { }; auto Contains = StringMatchOperator; -TypedValue Assert(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Assert(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("assert", args, nargs); if (!args[0].ValueBool()) { std::string message("Assertion failed"); @@ -808,9 +797,8 @@ TypedValue Assert(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, return TypedValue(args[0], ctx.memory); } -TypedValue Counter(TypedValue *args, int64_t nargs, - const EvaluationContext &context, - database::GraphDbAccessor *) { +TypedValue Counter(const TypedValue *args, int64_t nargs, + const FunctionContext &context) { FType>("counter", args, nargs); int64_t step = 1; if (nargs == 3) { @@ -818,15 +806,15 @@ TypedValue Counter(TypedValue *args, int64_t nargs, } auto [it, inserted] = - context.counters.emplace(args[0].ValueString(), args[1].ValueInt()); + context.counters->emplace(args[0].ValueString(), args[1].ValueInt()); auto value = it->second; it->second += step; return TypedValue(value, context.memory); } -TypedValue Id(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *dba) { +TypedValue Id(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("id", args, nargs); const auto &arg = args[0]; if (arg.IsVertex()) @@ -835,8 +823,8 @@ TypedValue Id(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, return TypedValue(arg.ValueEdge().CypherId(), ctx.memory); } -TypedValue ToString(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, database::GraphDbAccessor *) { +TypedValue ToString(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType>("toString", args, nargs); const auto &arg = args[0]; switch (arg.type()) { @@ -858,23 +846,22 @@ TypedValue ToString(TypedValue *args, int64_t nargs, } } -TypedValue Timestamp(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Timestamp(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType("timestamp", args, nargs); return TypedValue(ctx.timestamp, ctx.memory); } -TypedValue Left(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *dba) { +TypedValue Left(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType, Or>("left", args, nargs); if (args[0].IsNull() || args[1].IsNull()) return TypedValue(ctx.memory); return TypedValue(utils::Substr(args[0].ValueString(), 0, args[1].ValueInt()), ctx.memory); } -TypedValue Right(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *dba) { +TypedValue Right(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType, Or>("right", args, nargs); if (args[0].IsNull() || args[1].IsNull()) return TypedValue(ctx.memory); const auto &str = args[0].ValueString(); @@ -885,7 +872,7 @@ TypedValue Right(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, } TypedValue CallStringFunction( - TypedValue *args, int64_t nargs, utils::MemoryResource *memory, + const TypedValue *args, int64_t nargs, utils::MemoryResource *memory, const char *name, std::function fun) { FType>(name, args, nargs); @@ -893,39 +880,39 @@ TypedValue CallStringFunction( return TypedValue(fun(args[0].ValueString()), memory); } -TypedValue LTrim(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue LTrim(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { return CallStringFunction( args, nargs, ctx.memory, "lTrim", [&](const auto &str) { return TypedValue::TString(utils::LTrim(str), ctx.memory); }); } -TypedValue RTrim(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue RTrim(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { return CallStringFunction( args, nargs, ctx.memory, "rTrim", [&](const auto &str) { return TypedValue::TString(utils::RTrim(str), ctx.memory); }); } -TypedValue Trim(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Trim(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { return CallStringFunction( args, nargs, ctx.memory, "trim", [&](const auto &str) { return TypedValue::TString(utils::Trim(str), ctx.memory); }); } -TypedValue Reverse(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, database::GraphDbAccessor *) { +TypedValue Reverse(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { return CallStringFunction( args, nargs, ctx.memory, "reverse", [&](const auto &str) { return utils::Reversed(str, ctx.memory); }); } -TypedValue ToLower(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, database::GraphDbAccessor *) { +TypedValue ToLower(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { return CallStringFunction(args, nargs, ctx.memory, "toLower", [&](const auto &str) { TypedValue::TString res(ctx.memory); @@ -934,8 +921,8 @@ TypedValue ToLower(TypedValue *args, int64_t nargs, }); } -TypedValue ToUpper(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, database::GraphDbAccessor *) { +TypedValue ToUpper(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { return CallStringFunction(args, nargs, ctx.memory, "toUpper", [&](const auto &str) { TypedValue::TString res(ctx.memory); @@ -944,9 +931,8 @@ TypedValue ToUpper(TypedValue *args, int64_t nargs, }); } -TypedValue Replace(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, - database::GraphDbAccessor *dba) { +TypedValue Replace(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType, Or, Or>("replace", args, nargs); if (args[0].IsNull() || args[1].IsNull() || args[2].IsNull()) { @@ -958,8 +944,8 @@ TypedValue Replace(TypedValue *args, int64_t nargs, return TypedValue(std::move(replaced)); } -TypedValue Split(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, - database::GraphDbAccessor *dba) { +TypedValue Split(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType, Or>("split", args, nargs); if (args[0].IsNull() || args[1].IsNull()) { return TypedValue(ctx.memory); @@ -969,9 +955,8 @@ TypedValue Split(TypedValue *args, int64_t nargs, const EvaluationContext &ctx, return TypedValue(std::move(result)); } -TypedValue Substring(TypedValue *args, int64_t nargs, - const EvaluationContext &ctx, - database::GraphDbAccessor *) { +TypedValue Substring(const TypedValue *args, int64_t nargs, + const FunctionContext &ctx) { FType, NonNegativeInteger, Optional>( "substring", args, nargs); if (args[0].IsNull()) return TypedValue(ctx.memory); @@ -984,8 +969,8 @@ TypedValue Substring(TypedValue *args, int64_t nargs, } // namespace -std::function +std::function NameToFunction(const std::string &function_name) { // Scalar functions if (function_name == "DEGREE") return Degree; diff --git a/src/query/interpret/awesome_memgraph_functions.hpp b/src/query/interpret/awesome_memgraph_functions.hpp index dd4602d6f..e915d8c11 100644 --- a/src/query/interpret/awesome_memgraph_functions.hpp +++ b/src/query/interpret/awesome_memgraph_functions.hpp @@ -1,13 +1,19 @@ /// @file #pragma once -#include +#include +#include +#include -#include "query/typed_value.hpp" +#include "utils/memory.hpp" + +namespace database { +class GraphDbAccessor; +} namespace query { -struct EvaluationContext; +class TypedValue; namespace { const char kStartsWith[] = "STARTSWITH"; @@ -15,15 +21,21 @@ const char kEndsWith[] = "ENDSWITH"; const char kContains[] = "CONTAINS"; } // namespace +struct FunctionContext { + database::GraphDbAccessor *db_accessor; + utils::MemoryResource *memory; + int64_t timestamp; + std::unordered_map *counters; +}; + /// Return the function implementation with the given name. /// /// Note, returned function signature uses C-style access to an array to allow /// having an array stored anywhere the caller likes, as long as it is /// contiguous in memory. Since most functions don't take many arguments, it's /// convenient to have them stored in the calling stack frame. -std::function +std::function NameToFunction(const std::string &function_name); } // namespace query diff --git a/src/query/interpret/eval.hpp b/src/query/interpret/eval.hpp index 5e5bb41cd..26002e342 100644 --- a/src/query/interpret/eval.hpp +++ b/src/query/interpret/eval.hpp @@ -371,6 +371,8 @@ class ExpressionEvaluator : public ExpressionVisitor { } TypedValue Visit(Function &function) override { + FunctionContext function_ctx{dba_, ctx_->memory, ctx_->timestamp, + &ctx_->counters}; // Stack allocate evaluated arguments when there's a small number of them. if (function.arguments_.size() <= 8) { TypedValue arguments[8] = { @@ -382,7 +384,7 @@ class ExpressionEvaluator : public ExpressionVisitor { arguments[i] = function.arguments_[i]->Accept(*this); } auto res = function.function_(arguments, function.arguments_.size(), - *ctx_, dba_); + function_ctx); CHECK(res.GetMemoryResource() == ctx_->memory); return res; } else { @@ -392,7 +394,7 @@ class ExpressionEvaluator : public ExpressionVisitor { arguments.emplace_back(argument->Accept(*this)); } auto res = - function.function_(arguments.data(), arguments.size(), *ctx_, dba_); + function.function_(arguments.data(), arguments.size(), function_ctx); CHECK(res.GetMemoryResource() == ctx_->memory); return res; }