Query - LogicalOp - Filter op added
Reviewers: buda, teon.banek, mislav.bradac Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D176
This commit is contained in:
parent
1cf4b95c58
commit
eca90c43b3
@ -25,11 +25,12 @@ class ScanAll;
|
|||||||
class Expand;
|
class Expand;
|
||||||
class NodeFilter;
|
class NodeFilter;
|
||||||
class EdgeFilter;
|
class EdgeFilter;
|
||||||
|
class Filter;
|
||||||
class Produce;
|
class Produce;
|
||||||
|
|
||||||
using LogicalOperatorVisitor =
|
using LogicalOperatorVisitor =
|
||||||
::utils::Visitor<CreateNode, CreateExpand, ScanAll, Expand, NodeFilter,
|
::utils::Visitor<CreateNode, CreateExpand, ScanAll, Expand, NodeFilter,
|
||||||
EdgeFilter, Produce>;
|
EdgeFilter, Filter, Produce>;
|
||||||
|
|
||||||
class LogicalOperator : public ::utils::Visitable<LogicalOperatorVisitor> {
|
class LogicalOperator : public ::utils::Visitable<LogicalOperatorVisitor> {
|
||||||
public:
|
public:
|
||||||
@ -612,6 +613,56 @@ class EdgeFilter : public LogicalOperator {
|
|||||||
EdgeAtom *edge_atom_;
|
EdgeAtom *edge_atom_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter whose Pull returns true only when the given expression
|
||||||
|
* evaluates into true. The given expression is assumed to
|
||||||
|
* return either NULL (treated as false) or a boolean value.
|
||||||
|
*/
|
||||||
|
class Filter : public LogicalOperator {
|
||||||
|
public:
|
||||||
|
Filter(const std::shared_ptr<LogicalOperator> &input_,
|
||||||
|
Expression *expression_)
|
||||||
|
: input_(input_), expression_(expression_) {}
|
||||||
|
|
||||||
|
void Accept(LogicalOperatorVisitor &visitor) override {
|
||||||
|
visitor.Visit(*this);
|
||||||
|
input_->Accept(visitor);
|
||||||
|
visitor.PostVisit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
class FilterCursor : public Cursor {
|
||||||
|
public:
|
||||||
|
FilterCursor(Filter &self, GraphDbAccessor &db)
|
||||||
|
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||||
|
|
||||||
|
bool Pull(Frame &frame, SymbolTable &symbol_table) override {
|
||||||
|
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||||
|
while (input_cursor_->Pull(frame, symbol_table)) {
|
||||||
|
self_.expression_->Accept(evaluator);
|
||||||
|
TypedValue result = evaluator.PopBack();
|
||||||
|
if (result.type() == TypedValue::Type::Null || !result.Value<bool>())
|
||||||
|
continue;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Filter &self_;
|
||||||
|
std::unique_ptr<Cursor> input_cursor_;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::unique_ptr<Cursor> MakeCursor(GraphDbAccessor &db) override {
|
||||||
|
return std::make_unique<FilterCursor>(*this, db);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<LogicalOperator> input_;
|
||||||
|
Expression *expression_;
|
||||||
|
};
|
||||||
|
|
||||||
class Produce : public LogicalOperator {
|
class Produce : public LogicalOperator {
|
||||||
public:
|
public:
|
||||||
Produce(std::shared_ptr<LogicalOperator> input,
|
Produce(std::shared_ptr<LogicalOperator> input,
|
||||||
|
@ -903,3 +903,32 @@ TEST(ExpressionEvaluator, UnaryMinusOperator) {
|
|||||||
op->Accept(eval.eval);
|
op->Accept(eval.eval);
|
||||||
ASSERT_EQ(eval.eval.PopBack().Value<int64_t>(), -5);
|
ASSERT_EQ(eval.eval.PopBack().Value<int64_t>(), -5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Interpreter, Filter) {
|
||||||
|
Dbms dbms;
|
||||||
|
auto dba = dbms.active();
|
||||||
|
|
||||||
|
// add a 6 nodes with property 'prop', 2 have true as value
|
||||||
|
GraphDb::Property property = dba->property("Property");
|
||||||
|
for (int i = 0; i < 6; ++i)
|
||||||
|
dba->insert_vertex().PropsSet(property, i % 3 == 0);
|
||||||
|
dba->insert_vertex(); // prop not set, gives NULL
|
||||||
|
dba->advance_command();
|
||||||
|
|
||||||
|
AstTreeStorage storage;
|
||||||
|
SymbolTable symbol_table;
|
||||||
|
|
||||||
|
auto n = MakeScanAll(storage, symbol_table, "n");
|
||||||
|
auto e =
|
||||||
|
storage.Create<PropertyLookup>(storage.Create<Identifier>("n"), property);
|
||||||
|
symbol_table[*e->expression_] = std::get<2>(n);
|
||||||
|
auto f = std::make_shared<Filter>(std::get<1>(n), e);
|
||||||
|
|
||||||
|
auto output =
|
||||||
|
storage.Create<NamedExpression>("x", storage.Create<Identifier>("n"));
|
||||||
|
symbol_table[*output->expression_] = std::get<2>(n);
|
||||||
|
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1");
|
||||||
|
auto produce = MakeProduce(f, output);
|
||||||
|
|
||||||
|
EXPECT_EQ(CollectProduce(produce, symbol_table, *dba).GetResults().size(), 2);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user