Compare commits

...

1 Commits

Author SHA1 Message Date
Josip Mrden
59c05d83e9 Add rewrite of set property into set properties 2023-08-08 10:45:28 +02:00
11 changed files with 526 additions and 23 deletions

View File

@@ -2517,16 +2517,18 @@ class SetProperty : public memgraph::query::Clause {
bool Accept(HierarchicalTreeVisitor &visitor) override {
if (visitor.PreVisit(*this)) {
property_lookup_->Accept(visitor) && expression_->Accept(visitor);
identifier_->Accept(visitor) && property_lookup_->Accept(visitor) && expression_->Accept(visitor);
}
return visitor.PostVisit(*this);
}
memgraph::query::Identifier *identifier_{nullptr};
memgraph::query::PropertyLookup *property_lookup_{nullptr};
memgraph::query::Expression *expression_{nullptr};
SetProperty *Clone(AstStorage *storage) const override {
SetProperty *object = storage->Create<SetProperty>();
object->identifier_ = identifier_ ? identifier_->Clone(storage) : nullptr;
object->property_lookup_ = property_lookup_ ? property_lookup_->Clone(storage) : nullptr;
object->expression_ = expression_ ? expression_->Clone(storage) : nullptr;
return object;

View File

@@ -2550,6 +2550,10 @@ antlrcpp::Any CypherMainVisitor::visitSetItem(MemgraphCypher::SetItemContext *ct
auto *set_property = storage_->Create<SetProperty>();
set_property->property_lookup_ = std::any_cast<PropertyLookup *>(ctx->propertyExpression()->accept(this));
set_property->expression_ = std::any_cast<Expression *>(ctx->expression()->accept(this));
if (ctx->propertyExpression()->atom()->variable()) {
set_property->identifier_ = storage_->Create<Identifier>(
std::any_cast<std::string>(ctx->propertyExpression()->atom()->variable()->accept(this)));
}
return static_cast<Clause *>(set_property);
}

View File

@@ -2605,9 +2605,9 @@ void Delete::DeleteCursor::Shutdown() { input_cursor_->Shutdown(); }
void Delete::DeleteCursor::Reset() { input_cursor_->Reset(); }
SetProperty::SetProperty(const std::shared_ptr<LogicalOperator> &input, storage::PropertyId property,
PropertyLookup *lhs, Expression *rhs)
: input_(input), property_(property), lhs_(lhs), rhs_(rhs) {}
SetProperty::SetProperty(const std::shared_ptr<LogicalOperator> &input, Symbol input_symbol,
storage::PropertyId property, PropertyLookup *lhs, Expression *rhs)
: input_(input), input_symbol_(input_symbol), property_(property), lhs_(lhs), rhs_(rhs) {}
ACCEPT_WITH_INPUT(SetProperty)

View File

@@ -1170,8 +1170,8 @@ class SetProperty : public memgraph::query::plan::LogicalOperator {
SetProperty() {}
SetProperty(const std::shared_ptr<LogicalOperator> &input, storage::PropertyId property, PropertyLookup *lhs,
Expression *rhs);
SetProperty(const std::shared_ptr<LogicalOperator> &input, Symbol input_symbol, storage::PropertyId property,
PropertyLookup *lhs, Expression *rhs);
bool Accept(HierarchicalLogicalOperatorVisitor &visitor) override;
UniqueCursorPtr MakeCursor(utils::MemoryResource *) const override;
std::vector<Symbol> ModifiedSymbols(const SymbolTable &) const override;
@@ -1181,6 +1181,7 @@ class SetProperty : public memgraph::query::plan::LogicalOperator {
void set_input(std::shared_ptr<LogicalOperator> input) override { input_ = input; }
std::shared_ptr<memgraph::query::plan::LogicalOperator> input_;
Symbol input_symbol_;
storage::PropertyId property_;
PropertyLookup *lhs_;
Expression *rhs_;
@@ -1188,6 +1189,7 @@ class SetProperty : public memgraph::query::plan::LogicalOperator {
std::unique_ptr<LogicalOperator> Clone(AstStorage *storage) const override {
auto object = std::make_unique<SetProperty>();
object->input_ = input_ ? input_->Clone(storage) : nullptr;
object->input_symbol_ = input_symbol_;
object->property_ = property_;
object->lhs_ = lhs_ ? lhs_->Clone(storage) : nullptr;
object->rhs_ = rhs_ ? rhs_->Clone(storage) : nullptr;

View File

@@ -22,6 +22,7 @@
#include "query/plan/preprocess.hpp"
#include "query/plan/pretty_print.hpp"
#include "query/plan/rewrite/index_lookup.hpp"
#include "query/plan/rewrite/set_property.hpp"
#include "query/plan/rule_based_planner.hpp"
#include "query/plan/variable_start_planner.hpp"
#include "query/plan/vertex_count_cache.hpp"
@@ -43,7 +44,10 @@ class PostProcessor final {
template <class TPlanningContext>
std::unique_ptr<LogicalOperator> Rewrite(std::unique_ptr<LogicalOperator> plan, TPlanningContext *context) {
return RewriteWithIndexLookup(std::move(plan), context->symbol_table, context->ast_storage, context->db);
auto rewritten_plan =
RewriteWithIndexLookup(std::move(plan), context->symbol_table, context->ast_storage, context->db);
return RewriteWithSetPropertyToSetProperties(std::move(rewritten_plan), context->symbol_table, context->ast_storage,
context->db);
}
template <class TVertexCounts>

View File

@@ -0,0 +1,485 @@
// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
// License, and you may not use this file except in compliance with the Business Source License.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
/// @file
/// This file provides a plan rewriter which replaces `Filter` and `ScanAll`
/// operations with `ScanAllBy<Index>` if possible. The public entrypoint is
/// `RewriteWithIndexLookup`.
#pragma once
#include <algorithm>
#include <any>
#include <memory>
#include <optional>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "query/plan/operator.hpp"
#include "query/plan/preprocess.hpp"
namespace memgraph::query::plan {
namespace impl {
template <class TDbAccessor>
class SetPropertyRewritter final : public HierarchicalLogicalOperatorVisitor {
public:
SetPropertyRewritter(SymbolTable *symbol_table, AstStorage *ast_storage, TDbAccessor *db)
: symbol_table_(symbol_table), ast_storage_(ast_storage), db_(db) {}
using HierarchicalLogicalOperatorVisitor::PostVisit;
using HierarchicalLogicalOperatorVisitor::PreVisit;
using HierarchicalLogicalOperatorVisitor::Visit;
bool Visit(Once &) override { return true; }
bool PreVisit(Filter &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(Filter &op) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(ScanAll &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(ScanAll &scan) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Expand &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(Expand &expand) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(ExpandVariable &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(ExpandVariable &expand) override {
prev_ops_.pop_back();
return true;
}
// The following operators may only use index lookup in filters inside of
// their own branches. So we handle them all the same.
// * Input operator is visited with the current visitor.
// * Custom operator branches are visited with a new visitor.
bool PreVisit(Merge &op) override {
prev_ops_.push_back(&op);
op.input()->Accept(*this);
RewriteBranch(&op.merge_match_);
return false;
}
bool PostVisit(Merge &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Optional &op) override {
prev_ops_.push_back(&op);
op.input()->Accept(*this);
RewriteBranch(&op.optional_);
return false;
}
bool PostVisit(Optional &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Cartesian &op) override {
prev_ops_.push_back(&op);
RewriteBranch(&op.left_op_);
RewriteBranch(&op.right_op_);
return false;
}
bool PostVisit(Cartesian &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Union &op) override {
prev_ops_.push_back(&op);
RewriteBranch(&op.left_op_);
RewriteBranch(&op.right_op_);
return false;
}
bool PostVisit(Union &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(CreateNode &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(CreateNode &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(CreateExpand &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(CreateExpand &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(ScanAllByLabel &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(ScanAllByLabel &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(ScanAllByLabelPropertyRange &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(ScanAllByLabelPropertyRange &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(ScanAllByLabelPropertyValue &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(ScanAllByLabelPropertyValue &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(ScanAllByLabelProperty &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(ScanAllByLabelProperty &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(ScanAllById &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(ScanAllById &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(ConstructNamedPath &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(ConstructNamedPath &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Produce &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(Produce &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(EmptyResult &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(EmptyResult &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Delete &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(Delete &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(SetProperty &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(SetProperty &op) override {
prev_ops_.pop_back();
if (op.input_->GetTypeInfo() == SetProperty::kType) {
auto *set_prop_op = static_cast<SetProperty *>(op.input_.get());
MergeSetPropertyWithSetProperty(op, *set_prop_op);
} else if (op.input_->GetTypeInfo() == SetProperties::kType) {
auto *set_props_op = static_cast<SetProperties *>(op.input_.get());
MergeSetPropertyWithSetProperties(op, *set_props_op);
}
return true;
}
bool PreVisit(SetProperties &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(SetProperties &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(SetLabels &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(SetLabels &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(RemoveProperty &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(RemoveProperty &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(RemoveLabels &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(RemoveLabels &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(EdgeUniquenessFilter &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(EdgeUniquenessFilter &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Accumulate &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(Accumulate &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Aggregate &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(Aggregate &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Skip &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(Skip &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Limit &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(Limit &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(OrderBy &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(OrderBy &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Unwind &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(Unwind &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Distinct &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(Distinct &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(CallProcedure &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(CallProcedure &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Foreach &op) override {
prev_ops_.push_back(&op);
op.input()->Accept(*this);
RewriteBranch(&op.update_clauses_);
return false;
}
bool PostVisit(Foreach &) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(EvaluatePatternFilter &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(EvaluatePatternFilter & /*op*/) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(Apply &op) override {
prev_ops_.push_back(&op);
op.input()->Accept(*this);
RewriteBranch(&op.subquery_);
return false;
}
bool PostVisit(Apply & /*op*/) override {
prev_ops_.pop_back();
return true;
}
bool PreVisit(LoadCsv &op) override {
prev_ops_.push_back(&op);
return true;
}
bool PostVisit(LoadCsv & /*op*/) override {
prev_ops_.pop_back();
return true;
}
std::shared_ptr<LogicalOperator> new_root_;
private:
SymbolTable *symbol_table_;
AstStorage *ast_storage_;
TDbAccessor *db_;
std::vector<LogicalOperator *> prev_ops_;
bool DefaultPreVisit() override { throw utils::NotYetImplemented("optimizing set property"); }
void MergeSetPropertyWithSetProperty(SetProperty &op, SetProperty &child) {
if (child.input_symbol_ == op.input_symbol_) {
std::unordered_map<PropertyIx, Expression *> elements;
elements.insert({child.lhs_->property_, child.rhs_});
elements.insert({op.lhs_->property_, op.rhs_});
auto *map_literal = ast_storage_->Create<MapLiteral>(elements);
std::unique_ptr<LogicalOperator> set_properties =
std::make_unique<SetProperties>(op.input_->input(), op.input_symbol_, map_literal, SetProperties::Op::UPDATE);
SetOnParent(std::move(set_properties));
}
}
void MergeSetPropertyWithSetProperties(SetProperty &op, SetProperties &child) {
if (child.input_symbol_ == op.input_symbol_) {
auto *old_map = utils::Downcast<MapLiteral>(child.rhs_);
old_map->elements_.insert({op.lhs_->property_, op.rhs_});
auto *map_literal = ast_storage_->Create<MapLiteral>(old_map->elements_);
std::unique_ptr<LogicalOperator> set_properties =
std::make_unique<SetProperties>(op.input_->input(), op.input_symbol_, map_literal, SetProperties::Op::UPDATE);
SetOnParent(std::move(set_properties));
}
}
void SetOnParent(const std::shared_ptr<LogicalOperator> &input) {
MG_ASSERT(input);
if (prev_ops_.empty()) {
MG_ASSERT(!new_root_);
new_root_ = input;
return;
}
prev_ops_.back()->set_input(input);
}
void RewriteBranch(std::shared_ptr<LogicalOperator> *branch) {
SetPropertyRewritter<TDbAccessor> rewriter(symbol_table_, ast_storage_, db_);
(*branch)->Accept(rewriter);
if (rewriter.new_root_) {
*branch = rewriter.new_root_;
}
}
};
} // namespace impl
template <class TDbAccessor>
std::unique_ptr<LogicalOperator> RewriteWithSetPropertyToSetProperties(std::unique_ptr<LogicalOperator> root_op,
SymbolTable *symbol_table,
AstStorage *ast_storage, TDbAccessor *db) {
impl::SetPropertyRewritter<TDbAccessor> rewriter(symbol_table, ast_storage, db);
root_op->Accept(rewriter);
if (rewriter.new_root_) {
throw utils::NotYetImplemented("optimizing set property");
}
return root_op;
}
} // namespace memgraph::query::plan

View File

@@ -392,8 +392,10 @@ class RuleBasedPlanner {
} else if (auto *del = utils::Downcast<query::Delete>(clause)) {
return std::make_unique<plan::Delete>(std::move(input_op), del->expressions_, del->detach_);
} else if (auto *set = utils::Downcast<query::SetProperty>(clause)) {
return std::make_unique<plan::SetProperty>(std::move(input_op), GetProperty(set->property_lookup_->property_),
set->property_lookup_, set->expression_);
const auto &input_symbol = symbol_table.at(*set->identifier_);
return std::make_unique<plan::SetProperty>(std::move(input_op), input_symbol,
GetProperty(set->property_lookup_->property_), set->property_lookup_,
set->expression_);
} else if (auto *set = utils::Downcast<query::SetProperties>(clause)) {
auto op = set->update_ ? plan::SetProperties::Op::UPDATE : plan::SetProperties::Op::REPLACE;
const auto &input_symbol = symbol_table.at(*set->identifier_);

View File

@@ -471,7 +471,8 @@ TYPED_TEST(PrintToJsonTest, SetProperty) {
memgraph::storage::PropertyId prop = this->dba.NameToProperty("prop");
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, this->GetSymbol("node"));
last_op = std::make_shared<plan::SetProperty>(last_op, prop, PROPERTY_LOOKUP(this->dba, "node", prop),
last_op = std::make_shared<plan::SetProperty>(last_op, this->GetSymbol("node"), prop,
PROPERTY_LOOKUP(this->dba, "node", prop),
ADD(PROPERTY_LOOKUP(this->dba, "node", prop), LITERAL(1)));
this->Check(last_op.get(), R"sep(
@@ -625,7 +626,8 @@ TYPED_TEST(PrintToJsonTest, Accumulate) {
memgraph::storage::PropertyId prop = this->dba.NameToProperty("prop");
auto node_sym = this->GetSymbol("node");
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, node_sym);
last_op = std::make_shared<plan::SetProperty>(last_op, prop, PROPERTY_LOOKUP(this->dba, "node", prop),
last_op = std::make_shared<plan::SetProperty>(last_op, this->GetSymbol("node"), prop,
PROPERTY_LOOKUP(this->dba, "node", prop),
ADD(PROPERTY_LOOKUP(this->dba, "node", prop), LITERAL(1)));
last_op = std::make_shared<plan::Accumulate>(last_op, std::vector<Symbol>{node_sym}, true);

View File

@@ -114,9 +114,9 @@ TYPED_TEST(QueryPlanTest, Accumulate) {
auto one = LITERAL(1);
auto n_p = PROPERTY_LOOKUP(dba, IDENT("n")->MapTo(n.sym_), prop);
auto set_n_p = std::make_shared<plan::SetProperty>(r_m.op_, prop, n_p, ADD(n_p, one));
auto set_n_p = std::make_shared<plan::SetProperty>(r_m.op_, n.sym_, prop, n_p, ADD(n_p, one));
auto m_p = PROPERTY_LOOKUP(dba, IDENT("m")->MapTo(r_m.node_sym_), prop);
auto set_m_p = std::make_shared<plan::SetProperty>(set_n_p, prop, m_p, ADD(m_p, one));
auto set_m_p = std::make_shared<plan::SetProperty>(set_n_p, r_m.node_sym_, prop, m_p, ADD(m_p, one));
std::shared_ptr<LogicalOperator> last_op = set_m_p;
if (accumulate) {

View File

@@ -1116,10 +1116,10 @@ TYPED_TEST(QueryPlanTest, SetProperty) {
auto literal = LITERAL(42);
auto n_p = PROPERTY_LOOKUP(dba, IDENT("n")->MapTo(n.sym_), prop1);
auto set_n_p = std::make_shared<plan::SetProperty>(r_m.op_, prop1, n_p, literal);
auto set_n_p = std::make_shared<plan::SetProperty>(r_m.op_, n.sym_, prop1, n_p, literal);
auto r_p = PROPERTY_LOOKUP(dba, IDENT("r")->MapTo(r_m.edge_sym_), prop1);
auto set_r_p = std::make_shared<plan::SetProperty>(set_n_p, prop1, r_p, literal);
auto set_r_p = std::make_shared<plan::SetProperty>(set_n_p, r_m.edge_sym_, prop1, r_p, literal);
auto context = MakeContext(this->storage, symbol_table, &dba);
EXPECT_EQ(2, PullAll(*set_r_p, &context));
dba.AdvanceCommand();
@@ -1518,7 +1518,7 @@ TYPED_TEST(QueryPlanTest, NodeFilterSet) {
// SET n.prop = n.prop + 1
auto set_prop = PROPERTY_LOOKUP(dba, IDENT("n")->MapTo(scan_all.sym_), prop);
auto add = ADD(set_prop, LITERAL(1));
auto set = std::make_shared<plan::SetProperty>(node_filter, prop.second, set_prop, add);
auto set = std::make_shared<plan::SetProperty>(node_filter, scan_all.sym_, prop.second, set_prop, add);
auto context = MakeContext(this->storage, symbol_table, &dba);
EXPECT_EQ(2, PullAll(*set, &context));
dba.AdvanceCommand();
@@ -1608,11 +1608,11 @@ TYPED_TEST(QueryPlanTest, Merge) {
auto r_m = MakeExpand(this->storage, symbol_table, std::make_shared<Once>(), n.sym_, "r", EdgeAtom::Direction::BOTH,
{}, "m", false, memgraph::storage::View::OLD);
auto m_p = PROPERTY_LOOKUP(dba, IDENT("m")->MapTo(r_m.node_sym_), prop);
auto m_set = std::make_shared<plan::SetProperty>(r_m.op_, prop.second, m_p, LITERAL(1));
auto m_set = std::make_shared<plan::SetProperty>(r_m.op_, r_m.node_sym_, prop.second, m_p, LITERAL(1));
// merge_create branch
auto n_p = PROPERTY_LOOKUP(dba, IDENT("n")->MapTo(n.sym_), prop);
auto n_set = std::make_shared<plan::SetProperty>(std::make_shared<Once>(), prop.second, n_p, LITERAL(2));
auto n_set = std::make_shared<plan::SetProperty>(std::make_shared<Once>(), n.sym_, prop.second, n_p, LITERAL(2));
auto merge = std::make_shared<plan::Merge>(n.op_, m_set, n_set);
auto context = MakeContext(this->storage, symbol_table, &dba);
@@ -1659,7 +1659,8 @@ TYPED_TEST(QueryPlanTest, SetPropertyOnNull) {
auto literal = LITERAL(42);
auto n_prop = PROPERTY_LOOKUP(dba, null, prop);
auto once = std::make_shared<Once>();
auto set_op = std::make_shared<plan::SetProperty>(once, prop.second, n_prop, literal);
auto set_op =
std::make_shared<plan::SetProperty>(once, symbol_table.CreateAnonymousSymbol(), prop.second, n_prop, literal);
auto context = MakeContext(this->storage, symbol_table, &dba);
EXPECT_EQ(1, PullAll(*set_op, &context));
}
@@ -1735,7 +1736,7 @@ TYPED_TEST(QueryPlanTest, DeleteSetProperty) {
auto delete_op = std::make_shared<plan::Delete>(n.op_, std::vector<Expression *>{n_get}, false);
auto prop = PROPERTY_PAIR(dba, "property");
auto n_prop = PROPERTY_LOOKUP(dba, IDENT("n")->MapTo(n.sym_), prop);
auto set_op = std::make_shared<plan::SetProperty>(delete_op, prop.second, n_prop, LITERAL(42));
auto set_op = std::make_shared<plan::SetProperty>(delete_op, n.sym_, prop.second, n_prop, LITERAL(42));
auto context = MakeContext(this->storage, symbol_table, &dba);
EXPECT_THROW(PullAll(*set_op, &context), QueryRuntimeException);
}
@@ -1866,7 +1867,7 @@ class UpdatePropertiesWithAuthFixture : public QueryPlanTest<StorageType> {
auto literal = LITERAL(new_property_value);
auto n_p = PROPERTY_LOOKUP(dba, IDENT("n")->MapTo(scan_all.sym_), entity_prop);
auto set_property = std::make_shared<plan::SetProperty>(scan_all.op_, entity_prop, n_p, literal);
auto set_property = std::make_shared<plan::SetProperty>(scan_all.op_, scan_all.sym_, entity_prop, n_p, literal);
// produce the node
auto output =
@@ -1888,7 +1889,7 @@ class UpdatePropertiesWithAuthFixture : public QueryPlanTest<StorageType> {
// set property to 2 on n
auto literal = LITERAL(new_property_value);
auto n_p = PROPERTY_LOOKUP(dba, IDENT("r")->MapTo(expand.edge_sym_), entity_prop);
auto set_property = std::make_shared<plan::SetProperty>(expand.op_, entity_prop, n_p, literal);
auto set_property = std::make_shared<plan::SetProperty>(expand.op_, scan_all.sym_, entity_prop, n_p, literal);
memgraph::glue::FineGrainedAuthChecker auth_checker{user, &dba};
auto context = MakeContextWithFineGrainedChecker(this->storage, symbol_table, &dba, &auth_checker);

View File

@@ -171,7 +171,8 @@ TYPED_TEST(ReadWriteTypeCheckTest, SetRemovePropertiesLabels) {
memgraph::storage::PropertyId prop = this->dba.NameToProperty("prop");
std::shared_ptr<LogicalOperator> last_op = std::make_shared<ScanAll>(nullptr, this->GetSymbol("node"));
last_op = std::make_shared<plan::SetProperty>(last_op, prop, PROPERTY_LOOKUP(this->dba, "node", prop),
last_op = std::make_shared<plan::SetProperty>(last_op, this->GetSymbol("node"), prop,
PROPERTY_LOOKUP(this->dba, "node", prop),
ADD(PROPERTY_LOOKUP(this->dba, "node", prop), LITERAL(1)));
last_op = std::make_shared<plan::RemoveProperty>(
last_op, this->dba.NameToProperty("prop"), PROPERTY_LOOKUP(this->dba, "node", this->dba.NameToProperty("prop")));