Add inDegree and outDegree functions

Reviewers: teon.banek, mtomic

Reviewed By: mtomic

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D1651
This commit is contained in:
Lovro Lugovic 2018-10-11 13:39:36 +02:00
parent 6525451489
commit 467e46c302
2 changed files with 68 additions and 0 deletions

View File

@ -182,6 +182,42 @@ TypedValue Degree(TypedValue *args, int64_t nargs, const EvaluationContext &,
}
}
TypedValue InDegree(TypedValue *args, int64_t nargs, const EvaluationContext &,
database::GraphDbAccessor *) {
if (nargs != 1) {
throw QueryRuntimeException("'inDegree' requires exactly one argument.");
}
switch (args[0].type()) {
case TypedValue::Type::Null:
return TypedValue::Null;
case TypedValue::Type::Vertex: {
auto &vertex = args[0].Value<VertexAccessor>();
return static_cast<int64_t>(vertex.in_degree());
}
default:
throw QueryRuntimeException("'inDegree' argument must be a node.");
}
}
TypedValue OutDegree(TypedValue *args, int64_t nargs, const EvaluationContext &,
database::GraphDbAccessor *) {
if (nargs != 1) {
throw QueryRuntimeException("'outDegree' requires exactly one argument.");
}
switch (args[0].type()) {
case TypedValue::Type::Null:
return TypedValue::Null;
case TypedValue::Type::Vertex: {
auto &vertex = args[0].Value<VertexAccessor>();
return static_cast<int64_t>(vertex.out_degree());
}
default:
throw QueryRuntimeException("'outDegree' argument must be a node.");
}
}
TypedValue ToBoolean(TypedValue *args, int64_t nargs, const EvaluationContext &,
database::GraphDbAccessor *) {
if (nargs != 1) {
@ -853,6 +889,8 @@ NameToFunction(const std::string &function_name) {
// Scalar functions
if (function_name == "COALESCE") return Coalesce;
if (function_name == "DEGREE") return Degree;
if (function_name == "INDEGREE") return InDegree;
if (function_name == "OUTDEGREE") return OutDegree;
if (function_name == "ENDNODE") return EndNode;
if (function_name == "HEAD") return Head;
if (function_name == "ID") return Id;

View File

@ -999,6 +999,36 @@ TEST_F(FunctionTest, Degree) {
ASSERT_THROW(EvaluateFunction("DEGREE", {e12}), QueryRuntimeException);
}
TEST_F(FunctionTest, InDegree) {
ASSERT_THROW(EvaluateFunction("INDEGREE", {}), QueryRuntimeException);
ASSERT_TRUE(EvaluateFunction("INDEGREE", {TypedValue::Null}).IsNull());
auto v1 = dba->InsertVertex();
auto v2 = dba->InsertVertex();
auto v3 = dba->InsertVertex();
auto e12 = dba->InsertEdge(v1, v2, dba->EdgeType("t"));
dba->InsertEdge(v3, v2, dba->EdgeType("t"));
ASSERT_EQ(EvaluateFunction("INDEGREE", {v1}).ValueInt(), 0);
ASSERT_EQ(EvaluateFunction("INDEGREE", {v2}).ValueInt(), 2);
ASSERT_EQ(EvaluateFunction("INDEGREE", {v3}).ValueInt(), 0);
ASSERT_THROW(EvaluateFunction("INDEGREE", {2}), QueryRuntimeException);
ASSERT_THROW(EvaluateFunction("INDEGREE", {e12}), QueryRuntimeException);
}
TEST_F(FunctionTest, OutDegree) {
ASSERT_THROW(EvaluateFunction("OUTDEGREE", {}), QueryRuntimeException);
ASSERT_TRUE(EvaluateFunction("OUTDEGREE", {TypedValue::Null}).IsNull());
auto v1 = dba->InsertVertex();
auto v2 = dba->InsertVertex();
auto v3 = dba->InsertVertex();
auto e12 = dba->InsertEdge(v1, v2, dba->EdgeType("t"));
dba->InsertEdge(v3, v2, dba->EdgeType("t"));
ASSERT_EQ(EvaluateFunction("OUTDEGREE", {v1}).ValueInt(), 1);
ASSERT_EQ(EvaluateFunction("OUTDEGREE", {v2}).ValueInt(), 0);
ASSERT_EQ(EvaluateFunction("OUTDEGREE", {v3}).ValueInt(), 1);
ASSERT_THROW(EvaluateFunction("OUTDEGREE", {2}), QueryRuntimeException);
ASSERT_THROW(EvaluateFunction("OUTDEGREE", {e12}), QueryRuntimeException);
}
TEST_F(FunctionTest, ToBoolean) {
ASSERT_THROW(EvaluateFunction("TOBOOLEAN", {}), QueryRuntimeException);
ASSERT_TRUE(EvaluateFunction("TOBOOLEAN", {TypedValue::Null}).IsNull());