Evaluate epressions EdgeTypeTest and LabelsTest

Reviewers: florijan, teon.banek

Reviewed By: teon.banek

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D345
This commit is contained in:
Mislav Bradac 2017-05-05 12:16:04 +02:00
parent 72d4a67c4a
commit cfb987a90c
3 changed files with 158 additions and 2 deletions

View File

@ -526,7 +526,10 @@ class EdgeTypeTest : public Expression {
protected:
EdgeTypeTest(int uid, Expression *expression,
std::vector<GraphDbTypes::EdgeType> edge_types)
: Expression(uid), expression_(expression), edge_types_(edge_types) {}
: Expression(uid), expression_(expression), edge_types_(edge_types) {
debug_assert(edge_types.size(),
"EdgeTypeTest must have at least one edge_type");
}
};
class Function : public Expression {

View File

@ -200,6 +200,51 @@ class ExpressionEvaluator : public TreeVisitorBase {
}
}
void PostVisit(LabelsTest &labels_test) override {
auto expression_result = PopBack();
switch (expression_result.type()) {
case TypedValue::Type::Null:
result_stack_.emplace_back(TypedValue::Null);
break;
case TypedValue::Type::Vertex: {
auto vertex = expression_result.Value<VertexAccessor>();
for (const auto label : labels_test.labels_) {
if (!vertex.has_label(label)) {
result_stack_.emplace_back(false);
return;
}
}
result_stack_.emplace_back(true);
break;
}
default:
throw TypedValueException("Expected Node in labels test");
}
}
void PostVisit(EdgeTypeTest &edge_type_test) override {
auto expression_result = PopBack();
switch (expression_result.type()) {
case TypedValue::Type::Null:
result_stack_.emplace_back(TypedValue::Null);
break;
case TypedValue::Type::Edge: {
auto real_edge_type =
expression_result.Value<EdgeAccessor>().edge_type();
for (const auto edge_type : edge_type_test.edge_types_) {
if (edge_type == real_edge_type) {
result_stack_.emplace_back(true);
return;
}
}
result_stack_.emplace_back(false);
break;
}
default:
throw TypedValueException("Expected Edge in edge type test");
}
}
void Visit(PrimitiveLiteral &literal) override {
// TODO: no need to evaluate constants, we can write it to frame in one
// of the previous phases.

View File

@ -7,11 +7,13 @@
#include "gtest/gtest.h"
#include "database/graph_db_accessor.hpp"
#include "database/graph_db_datatypes.hpp"
#include "dbms/dbms.hpp"
#include "query/frontend/ast/ast.hpp"
#include "query/frontend/opencypher/parser.hpp"
#include "query/interpret/awesome_memgraph_functions.hpp"
#include "query/interpret/eval.hpp"
#include "query/interpret/frame.hpp"
using namespace query;
using testing::Pair;
@ -22,7 +24,7 @@ namespace {
struct NoContextExpressionEvaluator {
NoContextExpressionEvaluator() {}
Frame frame{0};
Frame frame{128};
SymbolTable symbol_table;
Dbms dbms;
std::unique_ptr<GraphDbAccessor> dba = dbms.active();
@ -428,6 +430,112 @@ TEST(ExpressionEvaluator, IsNullOperator) {
ASSERT_EQ(eval.eval.PopBack().Value<bool>(), true);
}
TEST(ExpressionEvaluator, PropertyLookup) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
Dbms dbms;
auto dba = dbms.active();
auto v1 = dba->insert_vertex();
v1.PropsSet(dba->property("age"), 10);
auto *identifier = storage.Create<Identifier>("n");
auto node_symbol = eval.symbol_table.CreateSymbol("n");
eval.symbol_table[*identifier] = node_symbol;
eval.frame[node_symbol] = v1;
{
auto *op = storage.Create<PropertyLookup>(identifier, dba->property("age"));
op->Accept(eval.eval);
EXPECT_EQ(eval.eval.PopBack().Value<int64_t>(), 10);
}
{
auto *op =
storage.Create<PropertyLookup>(identifier, dba->property("height"));
op->Accept(eval.eval);
EXPECT_TRUE(eval.eval.PopBack().IsNull());
}
{
eval.frame[node_symbol] = TypedValue::Null;
auto *op = storage.Create<PropertyLookup>(identifier, dba->property("age"));
op->Accept(eval.eval);
EXPECT_TRUE(eval.eval.PopBack().IsNull());
}
}
TEST(ExpressionEvaluator, LabelsTest) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
Dbms dbms;
auto dba = dbms.active();
auto v1 = dba->insert_vertex();
v1.add_label(dba->label("ANIMAL"));
v1.add_label(dba->label("DOG"));
v1.add_label(dba->label("NICE_DOG"));
auto *identifier = storage.Create<Identifier>("n");
auto node_symbol = eval.symbol_table.CreateSymbol("n");
eval.symbol_table[*identifier] = node_symbol;
eval.frame[node_symbol] = v1;
{
auto *op = storage.Create<LabelsTest>(
identifier, std::vector<GraphDbTypes::Label>{dba->label("DOG"),
dba->label("ANIMAL")});
op->Accept(eval.eval);
EXPECT_EQ(eval.eval.PopBack().Value<bool>(), true);
}
{
auto *op = storage.Create<LabelsTest>(
identifier,
std::vector<GraphDbTypes::Label>{
dba->label("DOG"), dba->label("BAD_DOG"), dba->label("ANIMAL")});
op->Accept(eval.eval);
EXPECT_EQ(eval.eval.PopBack().Value<bool>(), false);
}
{
eval.frame[node_symbol] = TypedValue::Null;
auto *op = storage.Create<LabelsTest>(
identifier,
std::vector<GraphDbTypes::Label>{
dba->label("DOG"), dba->label("BAD_DOG"), dba->label("ANIMAL")});
op->Accept(eval.eval);
EXPECT_TRUE(eval.eval.PopBack().IsNull());
}
}
TEST(ExpressionEvaluator, EdgeTypeTest) {
AstTreeStorage storage;
NoContextExpressionEvaluator eval;
Dbms dbms;
auto dba = dbms.active();
auto v1 = dba->insert_vertex();
auto v2 = dba->insert_vertex();
auto e = dba->insert_edge(v1, v2, dba->edge_type("TYPE1"));
auto *identifier = storage.Create<Identifier>("e");
auto edge_symbol = eval.symbol_table.CreateSymbol("e");
eval.symbol_table[*identifier] = edge_symbol;
eval.frame[edge_symbol] = e;
{
auto *op = storage.Create<EdgeTypeTest>(
identifier, std::vector<GraphDbTypes::EdgeType>{
dba->edge_type("TYPE0"), dba->edge_type("TYPE1"),
dba->edge_type("TYPE2")});
op->Accept(eval.eval);
EXPECT_EQ(eval.eval.PopBack().Value<bool>(), true);
}
{
auto *op = storage.Create<EdgeTypeTest>(
identifier, std::vector<GraphDbTypes::EdgeType>{
dba->edge_type("TYPE0"), dba->edge_type("TYPE2")});
op->Accept(eval.eval);
EXPECT_EQ(eval.eval.PopBack().Value<bool>(), false);
}
{
eval.frame[edge_symbol] = TypedValue::Null;
auto *op = storage.Create<EdgeTypeTest>(
identifier, std::vector<GraphDbTypes::EdgeType>{
dba->edge_type("TYPE0"), dba->edge_type("TYPE2")});
op->Accept(eval.eval);
EXPECT_TRUE(eval.eval.PopBack().IsNull());
}
}
TEST(ExpressionEvaluator, Aggregation) {
AstTreeStorage storage;
auto aggr = storage.Create<Aggregation>(storage.Create<PrimitiveLiteral>(42),