Query::Plan::Produce - added support for Produce without input
Reviewers: teon.banek, buda Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D189
This commit is contained in:
parent
34cdbc2f39
commit
d387651205
@ -668,6 +668,17 @@ class Filter : public LogicalOperator {
|
||||
Expression *expression_;
|
||||
};
|
||||
|
||||
/**
|
||||
* A logical operator that places an arbitrary number
|
||||
* if named expressions on the frame (the logical operator
|
||||
* for the RETURN clause).
|
||||
*
|
||||
* Supports optional input. When the input is provided,
|
||||
* it is Pulled from and the Produce succeds once for
|
||||
* every input Pull (typically a MATCH/RETURN query).
|
||||
* When the input is not provided (typically a standalone
|
||||
* RETURN clause) the Produce's pull succeeds exactly once.
|
||||
*/
|
||||
class Produce : public LogicalOperator {
|
||||
public:
|
||||
Produce(std::shared_ptr<LogicalOperator> input,
|
||||
@ -678,7 +689,7 @@ class Produce : public LogicalOperator {
|
||||
|
||||
void Accept(LogicalOperatorVisitor &visitor) override {
|
||||
visitor.Visit(*this);
|
||||
input_->Accept(visitor);
|
||||
if (input_) input_->Accept(visitor);
|
||||
visitor.PostVisit(*this);
|
||||
}
|
||||
|
||||
@ -692,21 +703,32 @@ class Produce : public LogicalOperator {
|
||||
class ProduceCursor : public Cursor {
|
||||
public:
|
||||
ProduceCursor(Produce &self, GraphDbAccessor &db)
|
||||
: self_(self), input_cursor_(self_.input_->MakeCursor(db)) {}
|
||||
: self_(self),
|
||||
input_cursor_(self.input_ ? self_.input_->MakeCursor(db) : nullptr) {}
|
||||
bool Pull(Frame &frame, SymbolTable &symbol_table) override {
|
||||
ExpressionEvaluator evaluator(frame, symbol_table);
|
||||
if (input_cursor_->Pull(frame, symbol_table)) {
|
||||
for (auto named_expr : self_.named_expressions_) {
|
||||
named_expr->Accept(evaluator);
|
||||
if (input_cursor_) {
|
||||
if (input_cursor_->Pull(frame, symbol_table)) {
|
||||
for (auto named_expr : self_.named_expressions_)
|
||||
named_expr->Accept(evaluator);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else if (!did_produce_) {
|
||||
for (auto named_expr : self_.named_expressions_)
|
||||
named_expr->Accept(evaluator);
|
||||
did_produce_ = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
Produce &self_;
|
||||
// optional, see class documentation
|
||||
std::unique_ptr<Cursor> input_cursor_;
|
||||
// control switch when creating only one node (nullptr input)
|
||||
bool did_produce_{false};
|
||||
};
|
||||
|
||||
private:
|
||||
@ -787,7 +809,5 @@ class Delete : public LogicalOperator {
|
||||
// ignored when deleting edges
|
||||
bool detach_;
|
||||
};
|
||||
} // namespace plan
|
||||
} // namespace query
|
||||
|
||||
|
||||
} // namespace plan
|
||||
} // namespace query
|
||||
|
@ -156,10 +156,6 @@ auto GenMatch(Match &match, LogicalOperator *input_op,
|
||||
}
|
||||
|
||||
auto GenReturn(Return &ret, LogicalOperator *input_op) {
|
||||
if (!input_op) {
|
||||
// TODO: Support standalone RETURN clause (e.g. RETURN 2)
|
||||
throw NotYetImplemented();
|
||||
}
|
||||
return new Produce(std::shared_ptr<LogicalOperator>(input_op),
|
||||
ret.named_expressions_);
|
||||
}
|
||||
|
@ -143,6 +143,28 @@ TEST(Interpreter, MatchReturn) {
|
||||
EXPECT_EQ(result.GetResults().size(), 2);
|
||||
}
|
||||
|
||||
TEST(Interpreter, StandaloneReturn) {
|
||||
Dbms dbms;
|
||||
auto dba = dbms.active();
|
||||
|
||||
// add a few nodes to the database
|
||||
dba->insert_vertex();
|
||||
dba->insert_vertex();
|
||||
dba->advance_command();
|
||||
|
||||
AstTreeStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
auto output = NEXPR("n", LITERAL(42));
|
||||
auto produce = MakeProduce(std::shared_ptr<LogicalOperator>(nullptr), output);
|
||||
symbol_table[*output] = symbol_table.CreateSymbol("named_expression_1");
|
||||
|
||||
ResultStreamFaker result = CollectProduce(produce, symbol_table, *dba);
|
||||
EXPECT_EQ(result.GetResults().size(), 1);
|
||||
EXPECT_EQ(result.GetResults()[0].size(), 1);
|
||||
EXPECT_EQ(result.GetResults()[0][0].Value<int64_t>(), 42);
|
||||
}
|
||||
|
||||
TEST(Interpreter, NodeFilterLabelsAndProperties) {
|
||||
Dbms dbms;
|
||||
auto dba = dbms.active();
|
||||
|
Loading…
Reference in New Issue
Block a user