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:
parent
6a2d123f30
commit
47c1cd6e3d
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
"""
|
||||
|
@ -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(),
|
||||
|
Loading…
Reference in New Issue
Block a user