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:
parent
72d4a67c4a
commit
cfb987a90c
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user