Skip to content

Commit

Permalink
refactor delete info
Browse files Browse the repository at this point in the history
  • Loading branch information
andyfengHKU committed Jul 25, 2023
1 parent bfcedf7 commit e0a9d8f
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 59 deletions.
16 changes: 8 additions & 8 deletions src/binder/bind/bind_updating_clause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,11 +238,11 @@ std::unique_ptr<BoundUpdatingClause> Binder::bindDeleteClause(
case LogicalTypeID::NODE: {
auto deleteNodeInfo =
bindDeleteNodeInfo(static_pointer_cast<NodeExpression>(nodeOrRel));
boundDeleteClause->addNodeInfo(std::move(deleteNodeInfo));
boundDeleteClause->addInfo(std::move(deleteNodeInfo));
} break;
case LogicalTypeID::REL: {
auto deleteRel = bindDeleteRel(static_pointer_cast<RelExpression>(nodeOrRel));
boundDeleteClause->addDeleteRel(std::move(deleteRel));
auto deleteRel = bindDeleteRelInfo(static_pointer_cast<RelExpression>(nodeOrRel));
boundDeleteClause->addInfo(std::move(deleteRel));
} break;
default:
throw BinderException("Delete " + expressionTypeToString(nodeOrRel->expressionType) +
Expand All @@ -252,8 +252,7 @@ std::unique_ptr<BoundUpdatingClause> Binder::bindDeleteClause(
return boundDeleteClause;
}

std::unique_ptr<BoundDeleteNodeInfo> Binder::bindDeleteNodeInfo(
const std::shared_ptr<NodeExpression>& node) {
std::unique_ptr<BoundDeleteInfo> Binder::bindDeleteNodeInfo(std::shared_ptr<NodeExpression> node) {
if (node->isMultiLabeled()) {
throw BinderException(
"Delete node " + node->toString() + " with multiple node labels is not supported.");
Expand All @@ -262,16 +261,17 @@ std::unique_ptr<BoundDeleteNodeInfo> Binder::bindDeleteNodeInfo(
auto nodeTableSchema = catalog.getReadOnlyVersion()->getNodeTableSchema(nodeTableID);
auto primaryKeyExpression =
expressionBinder.bindNodePropertyExpression(*node, nodeTableSchema->getPrimaryKey().name);
return std::make_unique<BoundDeleteNodeInfo>(node, primaryKeyExpression);
auto extraInfo = std::make_unique<ExtraDeleteNodeInfo>(primaryKeyExpression);
return std::make_unique<BoundDeleteInfo>(UpdateTableType::NODE, node, std::move(extraInfo));
}

std::shared_ptr<RelExpression> Binder::bindDeleteRel(std::shared_ptr<RelExpression> rel) {
std::unique_ptr<BoundDeleteInfo> Binder::bindDeleteRelInfo(std::shared_ptr<RelExpression> rel) {
if (rel->isMultiLabeled() || rel->isBoundByMultiLabeledNode()) {
throw BinderException(
"Delete rel " + rel->toString() +
" with multiple rel labels or bound by multiple node labels is not supported.");
}
return rel;
return std::make_unique<BoundDeleteInfo>(UpdateTableType::REL, rel, nullptr /* extraInfo */);
}

} // namespace binder
Expand Down
26 changes: 17 additions & 9 deletions src/binder/query/bound_delete_clause.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,27 @@ namespace binder {

BoundDeleteClause::BoundDeleteClause(const BoundDeleteClause& other)
: BoundUpdatingClause{common::ClauseType::DELETE_} {
for (auto& deleteNodeInfo : other.deleteNodeInfos) {
deleteNodeInfos.push_back(deleteNodeInfo->copy());
for (auto& info : other.infos) {
infos.push_back(info->copy());
}
for (auto& deleteRel : other.deleteRels) {
deleteRels.push_back(deleteRel);
}

bool BoundDeleteClause::hasInfo(const std::function<bool(const BoundDeleteInfo&)>& check) const {
for (auto& info : infos) {
if (check(*info)) {
return true;
}
}
return false;
}

std::vector<BoundDeleteNodeInfo*> BoundDeleteClause::getNodeInfos() const {
std::vector<BoundDeleteNodeInfo*> result;
result.reserve(deleteNodeInfos.size());
for (auto& info : deleteNodeInfos) {
result.push_back(info.get());
std::vector<BoundDeleteInfo*> BoundDeleteClause::getInfos(
const std::function<bool(const BoundDeleteInfo&)>& check) const {
std::vector<BoundDeleteInfo*> result;
for (auto& info : infos) {
if (check(*info)) {
result.push_back(info.get());
}
}
return result;
}
Expand Down
8 changes: 5 additions & 3 deletions src/binder/visitor/property_collector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ void PropertyCollector::visitSet(const BoundUpdatingClause& updatingClause) {
void PropertyCollector::visitDelete(const BoundUpdatingClause& updatingClause) {
auto& boundDeleteClause = (BoundDeleteClause&)updatingClause;
for (auto& info : boundDeleteClause.getNodeInfos()) {
properties.insert(info->primaryKey);
auto extraInfo = (ExtraDeleteNodeInfo*)info->extraInfo.get();
properties.insert(extraInfo->primaryKey);
}
for (auto& deleteRel : boundDeleteClause.getDeleteRels()) {
properties.insert(deleteRel->getInternalIDProperty());
for (auto& info : boundDeleteClause.getRelInfos()) {
auto rel = (RelExpression*)info->nodeOrRel.get();
properties.insert(rel->getInternalIDProperty());
}
}

Expand Down
7 changes: 3 additions & 4 deletions src/include/binder/binder.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace binder {

class BoundCreateInfo;
class BoundSetPropertyInfo;
class BoundDeleteNodeInfo;
class BoundDeleteInfo;

// BinderScope keeps track of expressions in scope and their aliases. We maintain the order of
// expressions in
Expand Down Expand Up @@ -150,9 +150,8 @@ class Binder {
std::pair<parser::ParsedExpression*, parser::ParsedExpression*> setItem);
expression_pair bindSetItem(
std::pair<parser::ParsedExpression*, parser::ParsedExpression*> setItem);
std::unique_ptr<BoundDeleteNodeInfo> bindDeleteNodeInfo(
const std::shared_ptr<NodeExpression>& node);
std::shared_ptr<RelExpression> bindDeleteRel(std::shared_ptr<RelExpression> rel);
std::unique_ptr<BoundDeleteInfo> bindDeleteNodeInfo(std::shared_ptr<NodeExpression> node);
std::unique_ptr<BoundDeleteInfo> bindDeleteRelInfo(std::shared_ptr<RelExpression> rel);

/*** bind projection clause ***/
std::unique_ptr<BoundWithClause> bindWithClause(const parser::WithClause& withClause);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class BoundCreateClause : public BoundUpdatingClause {
return info.updateTableType == UpdateTableType::NODE;
});
}
std::vector<BoundCreateInfo*> getNodeInfos() const {
inline std::vector<BoundCreateInfo*> getNodeInfos() const {
return getInfos([](const BoundCreateInfo& info) {
return info.updateTableType == UpdateTableType::NODE;
});
Expand All @@ -29,7 +29,7 @@ class BoundCreateClause : public BoundUpdatingClause {
return info.updateTableType == UpdateTableType::REL;
});
}
std::vector<BoundCreateInfo*> getRelInfos() const {
inline std::vector<BoundCreateInfo*> getRelInfos() const {
return getInfos([](const BoundCreateInfo& info) {
return info.updateTableType == UpdateTableType::REL;
});
Expand Down
37 changes: 26 additions & 11 deletions src/include/binder/query/updating_clause/bound_delete_clause.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,40 @@ class BoundDeleteClause : public BoundUpdatingClause {
BoundDeleteClause() : BoundUpdatingClause{common::ClauseType::DELETE_} {};
BoundDeleteClause(const BoundDeleteClause& other);

inline void addNodeInfo(std::unique_ptr<BoundDeleteNodeInfo> info) {
deleteNodeInfos.push_back(std::move(info));
}
inline bool hasNodeInfo() const { return !deleteNodeInfos.empty(); }
std::vector<BoundDeleteNodeInfo*> getNodeInfos() const;
inline void addInfo(std::unique_ptr<BoundDeleteInfo> info) { infos.push_back(std::move(info)); }

inline void addDeleteRel(std::shared_ptr<RelExpression> deleteRel) {
deleteRels.push_back(std::move(deleteRel));
inline bool hasNodeInfo() const {
return hasInfo([](const BoundDeleteInfo& info) {
return info.updateTableType == UpdateTableType::NODE;
});
}
inline std::vector<BoundDeleteInfo*> getNodeInfos() const {
return getInfos([](const BoundDeleteInfo& info) {
return info.updateTableType == UpdateTableType::NODE;
});
}
inline bool hasRelInfo() const {
return hasInfo([](const BoundDeleteInfo& info) {
return info.updateTableType == UpdateTableType::REL;
});
}
inline std::vector<BoundDeleteInfo*> getRelInfos() const {
return getInfos([](const BoundDeleteInfo& info) {
return info.updateTableType == UpdateTableType::REL;
});
}
inline bool hasDeleteRel() const { return !deleteRels.empty(); }
inline std::vector<std::shared_ptr<RelExpression>> getDeleteRels() const { return deleteRels; }

inline std::unique_ptr<BoundUpdatingClause> copy() final {
return std::make_unique<BoundDeleteClause>(*this);
}

private:
std::vector<std::unique_ptr<BoundDeleteNodeInfo>> deleteNodeInfos;
std::vector<std::shared_ptr<RelExpression>> deleteRels;
bool hasInfo(const std::function<bool(const BoundDeleteInfo& info)>& check) const;
std::vector<BoundDeleteInfo*> getInfos(
const std::function<bool(const BoundDeleteInfo& info)>& check) const;

private:
std::vector<std::unique_ptr<BoundDeleteInfo>> infos;
};

} // namespace binder
Expand Down
42 changes: 33 additions & 9 deletions src/include/binder/query/updating_clause/bound_delete_info.h
Original file line number Diff line number Diff line change
@@ -1,22 +1,46 @@
#pragma once

#include "binder/expression/rel_expression.h"
#include "update_table_type.h"

namespace kuzu {
namespace binder {

struct BoundDeleteNodeInfo {
std::shared_ptr<NodeExpression> node;
struct ExtraDeleteInfo {
virtual ~ExtraDeleteInfo() = default;
virtual std::unique_ptr<ExtraDeleteInfo> copy() const = 0;
};

struct ExtraDeleteNodeInfo : public ExtraDeleteInfo {
std::shared_ptr<Expression> primaryKey;

BoundDeleteNodeInfo(
std::shared_ptr<NodeExpression> node, std::shared_ptr<Expression> primaryKey)
: node{std::move(node)}, primaryKey{std::move(primaryKey)} {}
BoundDeleteNodeInfo(const BoundDeleteNodeInfo& other)
: node{other.node}, primaryKey{other.primaryKey} {}
explicit ExtraDeleteNodeInfo(std::shared_ptr<Expression> primaryKey)
: primaryKey{std::move(primaryKey)} {}
ExtraDeleteNodeInfo(const ExtraDeleteNodeInfo& other) : primaryKey{other.primaryKey} {}

inline std::unique_ptr<ExtraDeleteInfo> copy() const final {
return std::make_unique<ExtraDeleteNodeInfo>(*this);
}
};

struct BoundDeleteInfo {
UpdateTableType updateTableType;
std::shared_ptr<Expression> nodeOrRel;
std::unique_ptr<ExtraDeleteInfo> extraInfo;

BoundDeleteInfo(UpdateTableType updateTableType, std::shared_ptr<Expression> nodeOrRel,
std::unique_ptr<ExtraDeleteInfo> extraInfo)
: updateTableType{updateTableType}, nodeOrRel{std::move(nodeOrRel)}, extraInfo{std::move(
extraInfo)} {}
BoundDeleteInfo(const BoundDeleteInfo& other)
: updateTableType{other.updateTableType}, nodeOrRel{other.nodeOrRel} {
if (other.extraInfo) {
extraInfo = other.extraInfo->copy();
}
}

inline std::unique_ptr<BoundDeleteNodeInfo> copy() {
return std::make_unique<BoundDeleteNodeInfo>(*this);
inline std::unique_ptr<BoundDeleteInfo> copy() {
return std::make_unique<BoundDeleteInfo>(*this);
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/include/binder/query/updating_clause/bound_set_clause.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class BoundSetClause : public BoundUpdatingClause {
return info.updateTableType == UpdateTableType::NODE;
});
}
std::vector<BoundSetPropertyInfo*> getNodeInfos() const {
inline std::vector<BoundSetPropertyInfo*> getNodeInfos() const {
return getInfos([](const BoundSetPropertyInfo& info) {
return info.updateTableType == UpdateTableType::NODE;
});
Expand All @@ -31,7 +31,7 @@ class BoundSetClause : public BoundUpdatingClause {
return info.updateTableType == UpdateTableType::REL;
});
}
std::vector<BoundSetPropertyInfo*> getRelInfos() const {
inline std::vector<BoundSetPropertyInfo*> getRelInfos() const {
return getInfos([](const BoundSetPropertyInfo& info) {
return info.updateTableType == UpdateTableType::REL;
});
Expand Down
8 changes: 3 additions & 5 deletions src/include/planner/query_planner.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace kuzu {
namespace binder {
class BoundCreateInfo;
class BoundSetPropertyInfo;
class BoundDeleteNodeInfo;
class BoundDeleteInfo;
} // namespace binder

namespace planner {
Expand Down Expand Up @@ -103,10 +103,8 @@ class QueryPlanner {
const std::vector<binder::BoundSetPropertyInfo*>& infos, LogicalPlan& plan);
void appendSetRelProperty(
const std::vector<binder::BoundSetPropertyInfo*>& infos, LogicalPlan& plan);
void appendDeleteNode(
const std::vector<binder::BoundDeleteNodeInfo*>& infos, LogicalPlan& plan);
void appendDeleteRel(
const std::vector<std::shared_ptr<binder::RelExpression>>& deleteRels, LogicalPlan& plan);
void appendDeleteNode(const std::vector<binder::BoundDeleteInfo*>& infos, LogicalPlan& plan);
void appendDeleteRel(const std::vector<binder::BoundDeleteInfo*>& infos, LogicalPlan& plan);

std::unique_ptr<LogicalPlan> createUnionPlan(
std::vector<std::unique_ptr<LogicalPlan>>& childrenPlans, bool isUnionAll);
Expand Down
15 changes: 11 additions & 4 deletions src/planner/plan/append_delete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ namespace kuzu {
namespace planner {

void QueryPlanner::appendDeleteNode(
const std::vector<binder::BoundDeleteNodeInfo*>& infos, LogicalPlan& plan) {
const std::vector<binder::BoundDeleteInfo*>& infos, LogicalPlan& plan) {
std::vector<std::shared_ptr<NodeExpression>> nodes;
expression_vector primaryKeys;
for (auto& info : infos) {
nodes.push_back(info->node);
primaryKeys.push_back(info->primaryKey);
auto node = std::static_pointer_cast<NodeExpression>(info->nodeOrRel);
auto extraInfo = (ExtraDeleteNodeInfo*)info->extraInfo.get();
nodes.push_back(node);
primaryKeys.push_back(extraInfo->primaryKey);
}
auto deleteNode = std::make_shared<LogicalDeleteNode>(
std::move(nodes), std::move(primaryKeys), plan.getLastOperator());
Expand All @@ -20,7 +22,12 @@ void QueryPlanner::appendDeleteNode(
}

void QueryPlanner::appendDeleteRel(
const std::vector<std::shared_ptr<binder::RelExpression>>& deleteRels, LogicalPlan& plan) {
const std::vector<binder::BoundDeleteInfo*>& infos, LogicalPlan& plan) {
std::vector<std::shared_ptr<RelExpression>> deleteRels;
for (auto& info : infos) {
auto rel = std::static_pointer_cast<RelExpression>(info->nodeOrRel);
deleteRels.push_back(rel);
}
auto deleteRel = std::make_shared<LogicalDeleteRel>(deleteRels, plan.getLastOperator());
for (auto i = 0u; i < deleteRel->getNumRels(); ++i) {
appendFlattens(deleteRel->getGroupsPosToFlatten(i), plan);
Expand Down
4 changes: 2 additions & 2 deletions src/planner/plan/plan_update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ void QueryPlanner::planDeleteClause(
binder::BoundUpdatingClause& updatingClause, LogicalPlan& plan) {
appendAccumulate(common::AccumulateType::REGULAR, plan);
auto& deleteClause = (BoundDeleteClause&)updatingClause;
if (deleteClause.hasDeleteRel()) {
appendDeleteRel(deleteClause.getDeleteRels(), plan);
if (deleteClause.hasRelInfo()) {
appendDeleteRel(deleteClause.getRelInfos(), plan);
}
if (deleteClause.hasNodeInfo()) {
appendDeleteNode(deleteClause.getNodeInfos(), plan);
Expand Down

0 comments on commit e0a9d8f

Please sign in to comment.