Degree(Vertex) function added

Summary:
- added only one function for getting the total (in + out) vertex degree, it's required for the Ravelin use-case
- specific `degree_in` and `degree_out` functions can be added as necessary
- also fixed random_graph_generator bug (needed it for testing)

Reviewers: buda, mislav.bradac

Reviewed By: buda, mislav.bradac

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D652
This commit is contained in:
florijan 2017-08-09 11:48:36 +02:00
parent 6a2d123f30
commit 47c1cd6e3d
6 changed files with 49 additions and 0 deletions

View File

@ -9,6 +9,7 @@
* Support for `all` function in openCypher.
* User specified transaction execution timeout.
* Support for query parameters (except for parameters in place of property maps).
* `degree` function added.
## v0.6.0

View File

@ -404,6 +404,7 @@ functions.
`coalesce` | Returns the first non null argument.
`startNode` | Returns the starting node of an edge.
`endNode` | Returns the destination node of an edge.
`degree` | Returns the number of edges (both incoming and outgoing) of a node.
`head` | Returns the first element of a list.
`last` | Returns the last element of a list.
`properties` | Returns the properties of a node or an edge.

View File

@ -153,6 +153,22 @@ TypedValue StartNode(const std::vector<TypedValue> &args, GraphDbAccessor &) {
}
}
TypedValue Degree(const std::vector<TypedValue> &args, GraphDbAccessor &) {
if (args.size() != 1U) {
throw QueryRuntimeException("degree requires 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() + vertex.in_degree());
}
default:
throw QueryRuntimeException("degree called with incompatible type");
}
}
TypedValue ToBoolean(const std::vector<TypedValue> &args, GraphDbAccessor &) {
if (args.size() != 1U) {
throw QueryRuntimeException("toBoolean requires one argument");
@ -492,6 +508,7 @@ NameToFunction(const std::string &function_name) {
if (function_name == "PROPERTIES") return Properties;
if (function_name == "SIZE") return Size;
if (function_name == "STARTNODE") return StartNode;
if (function_name == "DEGREE") return Degree;
if (function_name == "TOBOOLEAN") return ToBoolean;
if (function_name == "TOFLOAT") return ToFloat;
if (function_name == "TOINTEGER") return ToInteger;

View File

@ -151,6 +151,7 @@ class RandomGraphGenerator {
auto property = dba->property(prop_name);
for (VertexAccessor va : dba->vertices(false))
if (predicate(va)) va.PropsSet(property, value_generator());
dba->commit();
}
private:

View File

@ -487,6 +487,17 @@ Feature: Functions
| n | a | b |
| null | 3 | 2 |
Scenario: Degree test:
When executing query:
"""
CREATE (a)-[:Type]->(b)<-[:Type]-(c)
RETURN DEGREE(a) AS da, DEGREE(b) AS db, DEGREE(null) AS dn
"""
Then the result should be:
| da | db | dn |
| 1 | 2 | null |
Scenario: Last test:
When executing query:
"""

View File

@ -768,6 +768,24 @@ TEST(ExpressionEvaluator, FunctionStartNode) {
ASSERT_THROW(EvaluateFunction("STARTNODE", {2}), QueryRuntimeException);
}
TEST(ExpressionEvaluator, FunctionDegree) {
ASSERT_THROW(EvaluateFunction("DEGREE", {}), QueryRuntimeException);
ASSERT_EQ(EvaluateFunction("DEGREE", {TypedValue::Null}).type(),
TypedValue::Type::Null);
Dbms dbms;
auto dba = dbms.active();
auto v1 = dba->insert_vertex();
auto v2 = dba->insert_vertex();
auto v3 = dba->insert_vertex();
auto e12 = dba->insert_edge(v1, v2, dba->edge_type("t"));
dba->insert_edge(v3, v2, dba->edge_type("t"));
ASSERT_EQ(EvaluateFunction("DEGREE", {v1}).Value<int64_t>(), 1);
ASSERT_EQ(EvaluateFunction("DEGREE", {v2}).Value<int64_t>(), 2);
ASSERT_EQ(EvaluateFunction("DEGREE", {v3}).Value<int64_t>(), 1);
ASSERT_THROW(EvaluateFunction("DEGREE", {2}), QueryRuntimeException);
ASSERT_THROW(EvaluateFunction("DEGREE", {e12}), QueryRuntimeException);
}
TEST(ExpressionEvaluator, FunctionToBoolean) {
ASSERT_THROW(EvaluateFunction("TOBOOLEAN", {}), QueryRuntimeException);
ASSERT_EQ(EvaluateFunction("TOBOOLEAN", {TypedValue::Null}).type(),