Add planning Delete operation
Reviewers: florijan, mislav.bradac Reviewed By: florijan Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D188
This commit is contained in:
@@ -186,6 +186,9 @@ std::unique_ptr<LogicalOperator> MakeLogicalPlan(
|
||||
input_op = GenReturn(*ret, input_op);
|
||||
} else if (auto *create = dynamic_cast<Create *>(clause_ptr)) {
|
||||
input_op = GenCreate(*create, input_op, symbol_table, bound_symbols);
|
||||
} else if (auto *del = dynamic_cast<query::Delete *>(clause_ptr)) {
|
||||
input_op = new plan::Delete(std::shared_ptr<LogicalOperator>(input_op),
|
||||
del->expressions_, del->detach_);
|
||||
} else {
|
||||
throw NotYetImplemented();
|
||||
}
|
||||
|
||||
@@ -90,6 +90,18 @@ auto GetReturn(AstTreeStorage &storage,
|
||||
return ret;
|
||||
}
|
||||
|
||||
///
|
||||
/// Create the delete clause with given named expressions.
|
||||
///
|
||||
auto GetDelete(AstTreeStorage &storage, std::vector<Expression *> exprs,
|
||||
bool detach = false) {
|
||||
auto del = storage.Create<Delete>();
|
||||
del->expressions_.insert(del->expressions_.begin(), exprs.begin(),
|
||||
exprs.end());
|
||||
del->detach_ = detach;
|
||||
return del;
|
||||
}
|
||||
|
||||
} // namespace test_common
|
||||
|
||||
} // namespace query
|
||||
@@ -120,5 +132,8 @@ auto GetReturn(AstTreeStorage &storage,
|
||||
query::test_common::GetPropertyLookup(storage, __VA_ARGS__)
|
||||
#define NEXPR(name, expr) storage.Create<query::NamedExpression>((name), (expr))
|
||||
#define RETURN(...) query::test_common::GetReturn(storage, {__VA_ARGS__})
|
||||
#define DELETE(...) query::test_common::GetDelete(storage, {__VA_ARGS__})
|
||||
#define DETACH_DELETE(...) \
|
||||
query::test_common::GetDelete(storage, {__VA_ARGS__}, true)
|
||||
#define QUERY(...) query::test_common::GetQuery(storage, {__VA_ARGS__})
|
||||
#define LESS(expr1, expr2) storage.Create<query::LessOperator>((expr1), (expr2))
|
||||
|
||||
@@ -28,6 +28,7 @@ class PlanChecker : public LogicalOperatorVisitor {
|
||||
|
||||
void Visit(CreateNode &op) override { AssertType(op); }
|
||||
void Visit(CreateExpand &op) override { AssertType(op); }
|
||||
void Visit(Delete &op) override { AssertType(op); }
|
||||
void Visit(ScanAll &op) override { AssertType(op); }
|
||||
void Visit(Expand &op) override { AssertType(op); }
|
||||
void Visit(NodeFilter &op) override { AssertType(op); }
|
||||
@@ -145,4 +146,11 @@ TEST(TestLogicalPlanner, MatchWhereReturn) {
|
||||
typeid(Produce).hash_code()});
|
||||
}
|
||||
|
||||
TEST(TestLogicalPlanner, MatchDelete) {
|
||||
// Test MATCH (n) DELETE n
|
||||
AstTreeStorage storage;
|
||||
auto query = QUERY(MATCH(PATTERN(NODE("n"))), DELETE(IDENT("n")));
|
||||
CheckPlan(*query, {typeid(ScanAll).hash_code(), typeid(Delete).hash_code()});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -237,4 +237,28 @@ TEST(TestSymbolGenerator, MatchWhereUnbound) {
|
||||
EXPECT_THROW(query->Accept(symbol_generator), UnboundVariableError);
|
||||
}
|
||||
|
||||
TEST(TestSymbolGenerator, CreateDelete) {
|
||||
// Test CREATE (n) DELETE n
|
||||
AstTreeStorage storage;
|
||||
auto node = NODE("n");
|
||||
auto ident = IDENT("n");
|
||||
auto query = QUERY(CREATE(PATTERN(node)), DELETE(ident));
|
||||
SymbolTable symbol_table;
|
||||
SymbolGenerator symbol_generator(symbol_table);
|
||||
query->Accept(symbol_generator);
|
||||
EXPECT_EQ(symbol_table.max_position(), 1);
|
||||
auto node_symbol = symbol_table.at(*node->identifier_);
|
||||
auto ident_symbol = symbol_table.at(*ident);
|
||||
EXPECT_EQ(node_symbol, ident_symbol);
|
||||
}
|
||||
|
||||
TEST(TestSymbolGenerator, CreateDeleteUnbound) {
|
||||
// Test CREATE (n) DELETE missing
|
||||
AstTreeStorage storage;
|
||||
auto query = QUERY(CREATE(PATTERN(NODE("n"))), DELETE(IDENT("missing")));
|
||||
SymbolTable symbol_table;
|
||||
SymbolGenerator symbol_generator(symbol_table);
|
||||
EXPECT_THROW(query->Accept(symbol_generator), UnboundVariableError);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user