Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support delete vertex without edge #3316

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 75 additions & 71 deletions src/graph/validator/MutateValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,15 +306,17 @@ Status DeleteVerticesValidator::validateImpl() {
vertices_.emplace_back(std::move(idStatus).value());
}
}

auto ret = qctx_->schemaMng()->getAllEdge(spaceId_);
NG_RETURN_IF_ERROR(ret);
edgeNames_ = std::move(ret).value();
for (auto &name : edgeNames_) {
auto edgeStatus = qctx_->schemaMng()->toEdgeType(spaceId_, name);
NG_RETURN_IF_ERROR(edgeStatus);
auto edgeType = edgeStatus.value();
edgeTypes_.emplace_back(edgeType);
withEdge_ = sentence->withEdge();
if (withEdge_) {
auto ret = qctx_->schemaMng()->getAllEdge(spaceId_);
NG_RETURN_IF_ERROR(ret);
edgeNames_ = std::move(ret).value();
for (auto &name : edgeNames_) {
auto edgeStatus = qctx_->schemaMng()->toEdgeType(spaceId_, name);
NG_RETURN_IF_ERROR(edgeStatus);
auto edgeType = edgeStatus.value();
edgeTypes_.emplace_back(edgeType);
}
}
return Status::OK();
}
Expand Down Expand Up @@ -347,68 +349,71 @@ Status DeleteVerticesValidator::toPlan() {

auto *dedupVid = Dedup::make(qctx_, nullptr);
dedupVid->setInputVar(vidVar);
DeleteVertices *dvNode = nullptr;
if (withEdge_) {
std::vector<storage::cpp2::EdgeProp> edgeProps;
// make edgeRefs and edgeProp
auto index = 0u;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could iterates both edgeTypes_ and edgeNames_ instead of using the index.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not modify these codes, and just move them into an if statement.

DCHECK(edgeTypes_.size() == edgeNames_.size());
auto *pool = qctx_->objPool();
for (auto &name : edgeNames_) {
auto *edgeKeyRef = new EdgeKeyRef(EdgeSrcIdExpression::make(pool, name),
EdgeDstIdExpression::make(pool, name),
EdgeRankExpression::make(pool, name));
edgeKeyRef->setType(EdgeTypeExpression::make(pool, name));
qctx_->objPool()->add(edgeKeyRef);
edgeKeyRefs_.emplace_back(edgeKeyRef);

storage::cpp2::EdgeProp edgeProp;
edgeProp.set_type(edgeTypes_[index]);
edgeProp.props_ref().value().emplace_back(kSrc);
edgeProp.props_ref().value().emplace_back(kDst);
edgeProp.props_ref().value().emplace_back(kType);
edgeProp.props_ref().value().emplace_back(kRank);
edgeProps.emplace_back(edgeProp);

edgeProp.set_type(-edgeTypes_[index]);
edgeProps.emplace_back(std::move(edgeProp));
index++;
}

std::vector<storage::cpp2::EdgeProp> edgeProps;
// make edgeRefs and edgeProp
auto index = 0u;
DCHECK(edgeTypes_.size() == edgeNames_.size());
auto *pool = qctx_->objPool();
for (auto &name : edgeNames_) {
auto *edgeKeyRef = new EdgeKeyRef(EdgeSrcIdExpression::make(pool, name),
EdgeDstIdExpression::make(pool, name),
EdgeRankExpression::make(pool, name));
edgeKeyRef->setType(EdgeTypeExpression::make(pool, name));
qctx_->objPool()->add(edgeKeyRef);
edgeKeyRefs_.emplace_back(edgeKeyRef);

storage::cpp2::EdgeProp edgeProp;
edgeProp.set_type(edgeTypes_[index]);
edgeProp.props_ref().value().emplace_back(kSrc);
edgeProp.props_ref().value().emplace_back(kDst);
edgeProp.props_ref().value().emplace_back(kType);
edgeProp.props_ref().value().emplace_back(kRank);
edgeProps.emplace_back(edgeProp);

edgeProp.set_type(-edgeTypes_[index]);
edgeProps.emplace_back(std::move(edgeProp));
index++;
}

auto vertexPropsPtr = std::make_unique<std::vector<storage::cpp2::VertexProp>>();
auto edgePropsPtr = std::make_unique<std::vector<storage::cpp2::EdgeProp>>(edgeProps);
auto statPropsPtr = std::make_unique<std::vector<storage::cpp2::StatProp>>();
auto exprPtr = std::make_unique<std::vector<storage::cpp2::Expr>>();
auto *getNeighbors = GetNeighbors::make(qctx_,
dedupVid,
spaceId_,
vidRef_,
edgeTypes_,
storage::cpp2::EdgeDirection::BOTH,
nullptr,
std::move(edgePropsPtr),
std::move(statPropsPtr),
std::move(exprPtr));

auto *yieldColumns = pool->makeAndAdd<YieldColumns>();
yieldColumns->addColumn(new YieldColumn(EdgeSrcIdExpression::make(pool, "*"), kSrc));
yieldColumns->addColumn(new YieldColumn(EdgeTypeExpression::make(pool, "*"), kType));
yieldColumns->addColumn(new YieldColumn(EdgeRankExpression::make(pool, "*"), kRank));
yieldColumns->addColumn(new YieldColumn(EdgeDstIdExpression::make(pool, "*"), kDst));
auto *edgeKey = Project::make(qctx_, getNeighbors, yieldColumns);

auto *dedupEdgeKey = Dedup::make(qctx_, edgeKey);

// create deleteEdges node
auto *edgeKeyRef = pool->makeAndAdd<EdgeKeyRef>(InputPropertyExpression::make(pool, kSrc),
InputPropertyExpression::make(pool, kDst),
InputPropertyExpression::make(pool, kRank),
true);
edgeKeyRef->setType(InputPropertyExpression::make(pool, kType));
auto *deNode = DeleteEdges::make(qctx_, dedupEdgeKey, spaceId_, edgeKeyRef);

auto *dvNode = DeleteVertices::make(qctx_, deNode, spaceId_, vidRef_);

dvNode->setInputVar(dedupVid->outputVar());
auto vertexPropsPtr = std::make_unique<std::vector<storage::cpp2::VertexProp>>();
auto edgePropsPtr = std::make_unique<std::vector<storage::cpp2::EdgeProp>>(edgeProps);
auto statPropsPtr = std::make_unique<std::vector<storage::cpp2::StatProp>>();
auto exprPtr = std::make_unique<std::vector<storage::cpp2::Expr>>();
auto *getNeighbors = GetNeighbors::make(qctx_,
dedupVid,
spaceId_,
vidRef_,
edgeTypes_,
storage::cpp2::EdgeDirection::BOTH,
nullptr,
std::move(edgePropsPtr),
std::move(statPropsPtr),
std::move(exprPtr));

auto *yieldColumns = pool->makeAndAdd<YieldColumns>();
yieldColumns->addColumn(new YieldColumn(EdgeSrcIdExpression::make(pool, "*"), kSrc));
yieldColumns->addColumn(new YieldColumn(EdgeTypeExpression::make(pool, "*"), kType));
yieldColumns->addColumn(new YieldColumn(EdgeRankExpression::make(pool, "*"), kRank));
yieldColumns->addColumn(new YieldColumn(EdgeDstIdExpression::make(pool, "*"), kDst));
auto *edgeKey = Project::make(qctx_, getNeighbors, yieldColumns);

auto *dedupEdgeKey = Dedup::make(qctx_, edgeKey);

// create deleteEdges node
auto *edgeKeyRef = pool->makeAndAdd<EdgeKeyRef>(InputPropertyExpression::make(pool, kSrc),
InputPropertyExpression::make(pool, kDst),
InputPropertyExpression::make(pool, kRank),
true);
edgeKeyRef->setType(InputPropertyExpression::make(pool, kType));
auto *deNode = DeleteEdges::make(qctx_, dedupEdgeKey, spaceId_, edgeKeyRef);

dvNode = DeleteVertices::make(qctx_, deNode, spaceId_, vidRef_);
dvNode->setInputVar(dedupVid->outputVar());
} else {
dvNode = DeleteVertices::make(qctx_, dedupVid, spaceId_, vidRef_);
}
root_ = dvNode;
tail_ = dedupVid;
return Status::OK();
Expand All @@ -417,7 +422,6 @@ Status DeleteVerticesValidator::toPlan() {
Status DeleteTagsValidator::validateImpl() {
auto sentence = static_cast<DeleteTagsSentence *>(sentence_);
spaceId_ = vctx_->whichSpace().id;

if (sentence->vertices()->isRef()) {
vidRef_ = sentence->vertices()->ref();
auto type = deduceExprType(vidRef_);
Expand Down
1 change: 1 addition & 0 deletions src/graph/validator/MutateValidator.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class DeleteVerticesValidator final : public Validator {
std::vector<EdgeType> edgeTypes_;
std::vector<std::string> edgeNames_;
std::vector<EdgeKeyRef*> edgeKeyRefs_;
bool withEdge_{true};
};

class DeleteTagsValidator final : public Validator {
Expand Down
26 changes: 23 additions & 3 deletions src/graph/validator/test/MutateValidatorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ TEST_F(MutateValidatorTest, InsertEdgeTest) {
TEST_F(MutateValidatorTest, DeleteVertexTest) {
// succeed
{
auto cmd = "DELETE VERTEX \"A\"";
auto cmd = "DELETE VERTEX \"A\" WITH EDGE";
std::vector<PlanNode::Kind> expected = {
PK::kDeleteVertices,
PK::kDeleteEdges,
Expand All @@ -73,9 +73,18 @@ TEST_F(MutateValidatorTest, DeleteVertexTest) {
};
ASSERT_TRUE(checkResult(cmd, expected));
}
{
auto cmd = "DELETE VERTEX \"A\"";
std::vector<PlanNode::Kind> expected = {
PK::kDeleteVertices,
PK::kDedup,
PK::kStart,
};
ASSERT_TRUE(checkResult(cmd, expected));
}
// pipe
{
auto cmd = "GO FROM \"C\" OVER like YIELD like._dst as dst | DELETE VERTEX $-.dst";
auto cmd = "GO FROM \"C\" OVER like YIELD like._dst as dst | DELETE VERTEX $-.dst WITH EDGE";
std::vector<PlanNode::Kind> expected = {
PK::kDeleteVertices,
PK::kDeleteEdges,
Expand All @@ -89,9 +98,20 @@ TEST_F(MutateValidatorTest, DeleteVertexTest) {
};
ASSERT_TRUE(checkResult(cmd, expected));
}
{
auto cmd = "GO FROM \"C\" OVER like YIELD like._dst as dst | DELETE VERTEX $-.dst";
std::vector<PlanNode::Kind> expected = {
PK::kDeleteVertices,
PK::kDedup,
PK::kProject,
PK::kGetNeighbors,
PK::kStart,
};
ASSERT_TRUE(checkResult(cmd, expected));
}
// pipe wrong input
{
auto cmd = "GO FROM \"C\" OVER E YIELD E._dst as dst | DELETE VERTEX $-.a";
auto cmd = "GO FROM \"C\" OVER E YIELD E._dst as dst | DELETE VERTEX $-.a WITH EDGE";
ASSERT_FALSE(checkResult(cmd));
}
}
Expand Down
12 changes: 8 additions & 4 deletions src/parser/MutateSentences.h
Original file line number Diff line number Diff line change
Expand Up @@ -405,18 +405,22 @@ class UpdateEdgeSentence final : public UpdateBaseSentence {

class DeleteVerticesSentence final : public Sentence {
public:
explicit DeleteVerticesSentence(VertexIDList *vidList)
: Sentence(Kind::kDeleteVertices), vertices_(new VerticesClause(vidList)) {}
DeleteVerticesSentence(VertexIDList *vidList, bool withEdge)
: Sentence(Kind::kDeleteVertices),
vertices_(new VerticesClause(vidList)),
withEdge_(withEdge) {}

explicit DeleteVerticesSentence(Expression *ref)
: Sentence(Kind::kDeleteVertices), vertices_(new VerticesClause(ref)) {}
DeleteVerticesSentence(Expression *ref, bool withEdge)
: Sentence(Kind::kDeleteVertices), vertices_(new VerticesClause(ref)), withEdge_(withEdge) {}

const VerticesClause *vertices() const { return vertices_.get(); }

std::string toString() const override;
bool withEdge() const { return withEdge_; }

private:
std::unique_ptr<VerticesClause> vertices_;
bool withEdge_{true};
};

class DeleteTagsSentence final : public Sentence {
Expand Down
19 changes: 16 additions & 3 deletions src/parser/parser.yy
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ static constexpr size_t kCommentLengthLimit = 256;

%type <sentence> mutate_sentence
%type <sentence> insert_vertex_sentence insert_edge_sentence
%type <sentence> delete_vertex_sentence delete_edge_sentence delete_tag_sentence
%type <sentence> delete_vertex_sentence delete_edge_sentence delete_tag_sentence delete_vertex_with_edge_sentence
%type <sentence> update_vertex_sentence update_edge_sentence
%type <sentence> download_sentence ingest_sentence

Expand Down Expand Up @@ -2927,11 +2927,24 @@ update_edge_sentence

delete_vertex_sentence
: KW_DELETE KW_VERTEX vid_list {
auto sentence = new DeleteVerticesSentence($3);
auto sentence = new DeleteVerticesSentence($3, false);
$$ = sentence;
}
| KW_DELETE KW_VERTEX vid_ref_expression {
auto sentence = new DeleteVerticesSentence($3);
auto sentence = new DeleteVerticesSentence($3, false);
$$ = sentence;
}
| KW_DELETE KW_VERTEX delete_vertex_with_edge_sentence {
$$ = $3;
}
;
delete_vertex_with_edge_sentence
: vid_list KW_WITH KW_EDGE {
auto sentence = new DeleteVerticesSentence($1, true);
$$ = sentence;
}
| vid_ref_expression KW_WITH KW_EDGE {
auto sentence = new DeleteVerticesSentence($1, true);
$$ = sentence;
}
;
Expand Down
2 changes: 1 addition & 1 deletion tests/bench/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def delete(self, duration=0.000001):
for col in row.columns:
if col.getType() == ttypes.ColumnValue.ID:
id = col.get_id()
resp = self.execute('DELETE VERTEX {0}'.format(id))
resp = self.execute('DELETE VERTEX {0} WITH EDGE'.format(id))
self.check_resp_succeeded(resp)

resp = self.execute('lookup on person where person.age == {0} '.format(i))
Expand Down
2 changes: 1 addition & 1 deletion tests/query/bugs/fixed_delete_vertex_1996.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def test_issue1996(self):
time.sleep(self.delay)
resp = self.execute('INSERT VERTEX person(name, age) VALUES 101:("Tony Parker", 36)')
self.check_resp_succeeded(resp)
resp = self.execute('DELETE VERTEX 101')
resp = self.execute('DELETE VERTEX 101 WITH EDGE')
self.check_resp_succeeded(resp)

@classmethod
Expand Down
20 changes: 10 additions & 10 deletions tests/tck/features/delete/DeleteVertex.IntVid.feature
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Feature: Delete int vid of vertex
# delete one vertex
When executing query:
"""
DELETE VERTEX hash("Tony Parker");
DELETE VERTEX hash("Tony Parker") WITH EDGE;
"""
Then the execution should be successful
# after delete to check value by fetch
Expand Down Expand Up @@ -89,7 +89,7 @@ Feature: Delete int vid of vertex
# delete multi vertexes
When executing query:
"""
DELETE VERTEX hash("LeBron James"), hash("Dwyane Wade"), hash("Carmelo Anthony");
DELETE VERTEX hash("LeBron James"), hash("Dwyane Wade"), hash("Carmelo Anthony") WITH EDGE;
"""
Then the execution should be successful
# after delete multi vertexes to check value by go
Expand Down Expand Up @@ -136,7 +136,7 @@ Feature: Delete int vid of vertex
# delete hash id vertex
When executing query:
"""
DELETE VERTEX hash("Grant Hill")
DELETE VERTEX hash("Grant Hill") WITH EDGE
"""
Then the execution should be successful
# after delete hash id vertex to check value by go
Expand Down Expand Up @@ -165,14 +165,14 @@ Feature: Delete int vid of vertex
# delete not existed vertex
When executing query:
"""
DELETE VERTEX hash("Non-existing Vertex")
DELETE VERTEX hash("Non-existing Vertex") WITH EDGE
"""
Then the execution should be successful
# delete a vertex without edges
When executing query:
"""
INSERT VERTEX player(name, age) VALUES hash("A Loner"): ("A Loner", 0);
DELETE VERTEX hash("A Loner");
DELETE VERTEX hash("A Loner") WITH EDGE;
"""
Then the execution should be successful
# check delete a vertex without edges
Expand All @@ -185,7 +185,7 @@ Feature: Delete int vid of vertex
# delete with no edge
When executing query:
"""
DELETE VERTEX hash("Nobody")
DELETE VERTEX hash("Nobody") WITH EDGE
"""
Then the execution should be successful
# check delete with no edge
Expand All @@ -201,7 +201,7 @@ Feature: Delete int vid of vertex
# test delete with pipe wrong vid type
When executing query:
"""
GO FROM hash("Boris Diaw") OVER like YIELD (string)like._src as id | DELETE VERTEX $-.id
GO FROM hash("Boris Diaw") OVER like YIELD (string)like._src as id | DELETE VERTEX $-.id WITH EDGE
"""
Then a SemanticError should be raised at runtime:
# delete with pipe, get result by go
Expand Down Expand Up @@ -232,7 +232,7 @@ Feature: Delete int vid of vertex
| "Manu Ginobili" |
When executing query:
"""
GO FROM hash("Boris Diaw") OVER like YIELD like._dst as id | DELETE VERTEX $-.id
GO FROM hash("Boris Diaw") OVER like YIELD like._dst as id | DELETE VERTEX $-.id WITH EDGE
"""
Then the execution should be successful
When executing query:
Expand All @@ -257,7 +257,7 @@ Feature: Delete int vid of vertex
Scenario: delete with pipe failed, because of the wrong vid type
When executing query:
"""
USE nba_int_vid;YIELD "Tom" as id | DELETE VERTEX $-.id;
USE nba_int_vid;YIELD "Tom" as id | DELETE VERTEX $-.id WITH EDGE;
"""
Then a SemanticError should be raised at runtime: The vid `$-.id' should be type of `INT', but was`STRING'
Then drop the used space
Expand Down Expand Up @@ -288,7 +288,7 @@ Feature: Delete int vid of vertex
| "Russell Westbrook" |
When executing query:
"""
$var = GO FROM hash("Russell Westbrook") OVER like YIELD like._dst as id; DELETE VERTEX $var.id
$var = GO FROM hash("Russell Westbrook") OVER like YIELD like._dst as id; DELETE VERTEX $var.id WITH EDGE
"""
Then the execution should be successful
When executing query:
Expand Down
Loading