Skip to content

Commit

Permalink
Support delete vertex without edge (#3316)
Browse files Browse the repository at this point in the history
* support delete vertex without edge

* fmt feature

Co-authored-by: Sophie <84560950+Sophie-Xie@users.noreply.github.com>
  • Loading branch information
cangfengzhs and Sophie-Xie committed Dec 7, 2021
1 parent 6300233 commit d6f83f3
Show file tree
Hide file tree
Showing 12 changed files with 276 additions and 104 deletions.
146 changes: 75 additions & 71 deletions src/graph/validator/MutateValidator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,15 +307,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 @@ -348,68 +350,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;
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 @@ -418,7 +423,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 @@ -365,7 +365,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 @@ -2971,11 +2971,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

0 comments on commit d6f83f3

Please sign in to comment.