Skip to content
This repository has been archived by the owner on Dec 1, 2022. It is now read-only.

fix report error when field type and value not match in update edge #486

Merged
Show file tree
Hide file tree
Changes from 2 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
7 changes: 6 additions & 1 deletion src/storage/exec/UpdateNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,12 @@ class UpdateEdgeNode : public UpdateNode<cpp2::EdgeKey> {
if (this->exeResult_ != nebula::cpp2::ErrorCode::SUCCEEDED) {
return folly::none;
}
return this->updateAndWriteBack(partId, edgeKey);
auto batch = this->updateAndWriteBack(partId, edgeKey);
if (batch == folly::none) {
// There is an error in updateAndWriteBack
this->exeResult_ = nebula::cpp2::ErrorCode::E_INVALID_DATA;
}
return batch;
} else {
// If filter out, StorageExpressionContext is set in filterNode
return folly::none;
Expand Down
92 changes: 91 additions & 1 deletion src/storage/test/UpdateEdgeTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2030,7 +2030,7 @@ TEST(UpdateEdgeTest, Upsert_Multi_edge_Test) {
VertexID dstId = "Spurs";
EdgeRanking rank = 1997;
EdgeType edgeType = 101;
// src = Brandon Ingram, edge_type = 101, ranking = 2016, dst = Lakers
// src = Tim Duncan, edge_type = 101, ranking = 1997, dst = Spurs
storage::cpp2::EdgeKey edgeKey;
edgeKey.set_src(srcId);
edgeKey.set_edge_type(edgeType);
Expand Down Expand Up @@ -2094,6 +2094,96 @@ TEST(UpdateEdgeTest, Upsert_Multi_edge_Test) {
EXPECT_EQ(19, val.getInt());
}


// upsert/update field type and value does not match test, failed
TEST(UpdateEdgeTest, Upsert_Field_Type_And_Value_Match_Test) {
fs::TempDir rootPath("/tmp/UpdateEdgeTest.XXXXXX");
mock::MockCluster cluster;
cluster.initStorageKV(rootPath.path());
auto* env = cluster.storageEnv_.get();
auto parts = cluster.getTotalParts();

GraphSpaceID spaceId = 1;
auto status = env->schemaMan_->getSpaceVidLen(spaceId);
ASSERT_TRUE(status.ok());
auto spaceVidLen = status.value();
ASSERT_TRUE(QueryTestUtils::mockEdgeData(env, parts));

LOG(INFO) << "Build UpdateEdgeRequest...";
cpp2::UpdateEdgeRequest req;

auto partId = std::hash<std::string>()("Tim Duncan") % parts + 1;
req.set_space_id(spaceId);
req.set_part_id(partId);
VertexID srcId = "Tim Duncan";
VertexID dstId = "Spurs";
EdgeRanking rank = 1997;
EdgeType edgeType = 101;
// src = Tim Duncan, edge_type = 101, ranking = 1997, dst = Spurs
storage::cpp2::EdgeKey edgeKey;
edgeKey.set_src(srcId);
edgeKey.set_edge_type(edgeType);
edgeKey.set_ranking(rank);
edgeKey.set_dst(dstId);
req.set_edge_key(edgeKey);

LOG(INFO) << "Build updated props...";
std::vector<cpp2::UpdatedProp> props;

// string: Serve.type_ = 2011(value int)
cpp2::UpdatedProp uProp1;
uProp1.set_name("type");
ConstantExpression val1(2016L);
uProp1.set_value(Expression::encode(val1));
props.emplace_back(uProp1);
req.set_updated_props(std::move(props));

LOG(INFO) << "Build yield...";
// Return serve props: playerName, teamName, teamCareer
std::vector<std::string> tmpProps;
EdgePropertyExpression edgePropExp1("101", "playerName");
tmpProps.emplace_back(Expression::encode(edgePropExp1));

EdgePropertyExpression edgePropExp2("101", "teamName");
tmpProps.emplace_back(Expression::encode(edgePropExp2));

EdgePropertyExpression edgePropExp3("101", "type");
tmpProps.emplace_back(Expression::encode(edgePropExp3));

addEdgePropInKey(tmpProps);

req.set_return_props(std::move(tmpProps));
req.set_insertable(true);

LOG(INFO) << "Test UpdateEdgeRequest...";
auto* processor = UpdateEdgeProcessor::instance(env, nullptr);
auto f = processor->getFuture();
processor->process(req);
auto resp = std::move(f).get();

LOG(INFO) << "Check the results...";
EXPECT_EQ(1, (*resp.result_ref()).failed_parts.size());

// get serve from kvstore directly
auto prefix = NebulaKeyUtils::edgePrefix(spaceVidLen, partId, srcId, edgeType, rank, dstId);
std::unique_ptr<kvstore::KVIterator> iter;
auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter);
EXPECT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret);
EXPECT_TRUE(iter && iter->valid());

auto reader = RowReaderWrapper::getEdgePropReader(env->schemaMan_,
spaceId,
std::abs(edgeType),
iter->val());
auto val = reader->getValueByName("playerName");
EXPECT_EQ("Tim Duncan", val.getStr());
val = reader->getValueByName("teamName");
EXPECT_EQ("Spurs", val.getStr());
val = reader->getValueByName("type");
EXPECT_EQ("zzzzz", val.getStr());
}


} // namespace storage
} // namespace nebula

Expand Down
75 changes: 75 additions & 0 deletions src/storage/test/UpdateVertexTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1435,6 +1435,81 @@ TEST(UpdateVertexTest, Upsert_Multi_tag_Test) {
EXPECT_EQ("Tim Duncan", val.getStr());
}


// upsert/update field type and value does not match test, failed
TEST(UpdateVertexTest, Upsert_Field_Type_And_Value_Match_Test) {
fs::TempDir rootPath("/tmp/UpdateVertexTest.XXXXXX");
mock::MockCluster cluster;
cluster.initStorageKV(rootPath.path());
auto* env = cluster.storageEnv_.get();
auto parts = cluster.getTotalParts();

GraphSpaceID spaceId = 1;
TagID tagId = 1;
auto status = env->schemaMan_->getSpaceVidLen(spaceId);
ASSERT_TRUE(status.ok());
auto spaceVidLen = status.value();

EXPECT_TRUE(mockVertexData(env, parts, spaceVidLen));

LOG(INFO) << "Build UpdateVertexRequest...";
cpp2::UpdateVertexRequest req;

req.set_space_id(spaceId);
auto partId = std::hash<std::string>()("Tim Duncan") % parts + 1;
VertexID vertexId("Tim Duncan");
req.set_part_id(partId);
req.set_vertex_id(vertexId);
req.set_tag_id(tagId);

LOG(INFO) << "Build updated props...";
std::vector<cpp2::UpdatedProp> updatedProps;

// string: player.country_ = 2011(value int)
cpp2::UpdatedProp uProp1;
uProp1.set_name("country");
ConstantExpression uVal1(2011L);
uProp1.set_value(Expression::encode(uVal1));
updatedProps.emplace_back(uProp1);
req.set_updated_props(std::move(updatedProps));


LOG(INFO) << "Build yield...";
// Return player props: name, age, country
std::vector<std::string> tmpProps;
SourcePropertyExpression sourcePropExp1("1", "name");
tmpProps.emplace_back(Expression::encode(sourcePropExp1));

addTagPropInKey(tmpProps);

req.set_return_props(std::move(tmpProps));
req.set_insertable(true);

LOG(INFO) << "Test UpdateVertexRequest...";
auto* processor = UpdateVertexProcessor::instance(env, nullptr);
auto f = processor->getFuture();
processor->process(req);
auto resp = std::move(f).get();

LOG(INFO) << "Check the results...";
EXPECT_EQ(1, (*resp.result_ref()).failed_parts.size());


// get player from kvstore directly
auto prefix = NebulaKeyUtils::vertexPrefix(spaceVidLen, partId, vertexId, tagId);
std::unique_ptr<kvstore::KVIterator> iter;
auto ret = env->kvstore_->prefix(spaceId, partId, prefix, &iter);
ASSERT_EQ(nebula::cpp2::ErrorCode::SUCCEEDED, ret);
EXPECT_TRUE(iter && iter->valid());

auto reader = RowReaderWrapper::getTagPropReader(env->schemaMan_, spaceId, tagId, iter->val());
auto val = reader->getValueByName("name");
EXPECT_EQ("Tim Duncan", val.getStr());
val = reader->getValueByName("country");
EXPECT_EQ("America", val.getStr());
}


} // namespace storage
} // namespace nebula

Expand Down