From 054c127175bdceb7322165c2bf0374741574cd34 Mon Sep 17 00:00:00 2001 From: Marin Tomic <marin.tomic@memgraph.io> Date: Fri, 15 Jun 2018 10:40:51 +0200 Subject: [PATCH] Implement toString function Summary: https://neo4j.com/docs/developer-manual/3.4/cypher/functions/string/#functions-tostring Reviewers: teon.banek, buda Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D1430 --- .../interpret/awesome_memgraph_functions.cpp | 24 ++++++++++ tests/unit/query_expression_evaluator.cpp | 44 +++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/src/query/interpret/awesome_memgraph_functions.cpp b/src/query/interpret/awesome_memgraph_functions.cpp index 53cf70c15..a9fb16341 100644 --- a/src/query/interpret/awesome_memgraph_functions.cpp +++ b/src/query/interpret/awesome_memgraph_functions.cpp @@ -655,6 +655,29 @@ TypedValue Id(const std::vector<TypedValue> &args, } } +TypedValue ToString(const std::vector<TypedValue> &args, + database::GraphDbAccessor &) { + if (args.size() != 1U) { + throw QueryRuntimeException("toString takes one argument"); + } + auto &arg = args[0]; + switch (arg.type()) { + case TypedValue::Type::Null: + return TypedValue::Null; + case TypedValue::Type::String: + return arg; + case TypedValue::Type::Int: + return std::to_string(arg.ValueInt()); + case TypedValue::Type::Double: + return std::to_string(arg.ValueDouble()); + case TypedValue::Type::Bool: + return arg.ValueBool() ? "true" : "false"; + default: + throw QueryRuntimeException( + "toString argument must be a number, string or boolean"); + } +} + } // namespace std::function<TypedValue(const std::vector<TypedValue> &, @@ -706,6 +729,7 @@ NameToFunction(const std::string &function_name) { if (function_name == "INDEXINFO") return IndexInfo; if (function_name == "WORKERID") return WorkerId; if (function_name == "ID") return Id; + if (function_name == "TOSTRING") return ToString; return nullptr; } } // namespace query diff --git a/tests/unit/query_expression_evaluator.cpp b/tests/unit/query_expression_evaluator.cpp index 0cd4b59bb..c319f6e2e 100644 --- a/tests/unit/query_expression_evaluator.cpp +++ b/tests/unit/query_expression_evaluator.cpp @@ -1424,4 +1424,48 @@ TEST(ExpressionEvaluator, FunctionWorkerIdSingleNode) { EXPECT_EQ(EvaluateFunction("WORKERID", {va}, db).Value<int64_t>(), db.WorkerId()); } + +TEST(ExpressionEvaluator, FunctionToStringNull) { + database::SingleNode db; + EXPECT_TRUE(EvaluateFunction("TOSTRING", {TypedValue::Null}, db).IsNull()); +} + +TEST(ExpressionEvaluator, FunctionToStringString) { + database::SingleNode db; + EXPECT_EQ(EvaluateFunction("TOSTRING", {""}, db).ValueString(), ""); + EXPECT_EQ( + EvaluateFunction("TOSTRING", {"this is a string"}, db).ValueString(), + "this is a string"); +} + +TEST(ExpressionEvaluator, FunctionToStringInteger) { + database::SingleNode db; + EXPECT_EQ(EvaluateFunction("TOSTRING", {-23321312}, db).ValueString(), + "-23321312"); + EXPECT_EQ(EvaluateFunction("TOSTRING", {0}, db).ValueString(), "0"); + EXPECT_EQ(EvaluateFunction("TOSTRING", {42}, db).ValueString(), "42"); +} + +TEST(ExpressionEvaluator, FunctionToStringDouble) { + database::SingleNode db; + EXPECT_EQ(EvaluateFunction("TOSTRING", {-42.42}, db).ValueString(), + "-42.420000"); + EXPECT_EQ(EvaluateFunction("TOSTRING", {0.0}, db).ValueString(), "0.000000"); + EXPECT_EQ(EvaluateFunction("TOSTRING", {238910.2313217}, db).ValueString(), + "238910.231322"); +} + +TEST(ExpressionEvaluator, FunctionToStringBool) { + database::SingleNode db; + EXPECT_EQ(EvaluateFunction("TOSTRING", {true}, db).ValueString(), "true"); + EXPECT_EQ(EvaluateFunction("TOSTRING", {false}, db).ValueString(), "false"); +} + +TEST(ExpressionEvaluator, FunctionToStringExceptions) { + database::SingleNode db; + EXPECT_THROW(EvaluateFunction("TOSTRING", {1, 2, 3}, db), + QueryRuntimeException); + std::vector<TypedValue> l{1, 2, 3}; + EXPECT_THROW(EvaluateFunction("TOSTRING", l, db), QueryRuntimeException); +} } // namespace