diff --git a/src/common/utils/NebulaKeyUtils.cpp b/src/common/utils/NebulaKeyUtils.cpp index 9e7cc2585f7..0323269cbf0 100644 --- a/src/common/utils/NebulaKeyUtils.cpp +++ b/src/common/utils/NebulaKeyUtils.cpp @@ -72,7 +72,20 @@ std::string NebulaKeyUtils::edgeKey(size_t vIdLen, .append(1, ev); return key; } - +// static +std::string NebulaKeyUtils::vertexKey(size_t vIdLen, + PartitionID partId, + const VertexID& vId, + char pad) { + CHECK_GE(vIdLen, vId.size()); + int32_t item = (partId << kPartitionOffset) | static_cast(NebulaKeyType::kVertex); + std::string key; + key.reserve(kTagLen + vIdLen); + key.append(reinterpret_cast(&item), sizeof(int32_t)) + .append(vId.data(), vId.size()) + .append(vIdLen - vId.size(), pad); + return key; +} // static std::string NebulaKeyUtils::systemCommitKey(PartitionID partId) { int32_t item = (partId << kPartitionOffset) | static_cast(NebulaKeyType::kSystem); diff --git a/src/common/utils/NebulaKeyUtils.h b/src/common/utils/NebulaKeyUtils.h index 0d0ba17ea24..2cb53d54af5 100644 --- a/src/common/utils/NebulaKeyUtils.h +++ b/src/common/utils/NebulaKeyUtils.h @@ -53,7 +53,7 @@ class NebulaKeyUtils final { static std::string lastKey(const std::string& prefix, size_t count); /** - * Generate vertex key for kv store + * Generate tag key for kv store * */ static std::string tagKey( size_t vIdLen, PartitionID partId, const VertexID& vId, TagID tagId, char pad = '\0'); @@ -65,7 +65,10 @@ class NebulaKeyUtils final { EdgeRanking rank, const VertexID& dstId, EdgeVerPlaceHolder ev = 1); - + static std::string vertexKey(size_t vIdLen, + PartitionID partId, + const VertexID& vId, + char pad = '\0'); static std::string systemCommitKey(PartitionID partId); static std::string systemPartKey(PartitionID partId); @@ -73,7 +76,7 @@ class NebulaKeyUtils final { static std::string kvKey(PartitionID partId, const folly::StringPiece& name); /** - * Prefix for vertex + * Prefix for tag * */ static std::string tagPrefix(size_t vIdLen, PartitionID partId, const VertexID& vId, TagID tagId); diff --git a/src/common/utils/Types.h b/src/common/utils/Types.h index 8012ac91305..88e74106edc 100644 --- a/src/common/utils/Types.h +++ b/src/common/utils/Types.h @@ -18,7 +18,7 @@ enum class NebulaKeyType : uint32_t { kSystem = 0x00000004, kOperation = 0x00000005, kKeyValue = 0x00000006, - // kVertex = 0x00000007, + kVertex = 0x00000007, }; enum class NebulaSystemKeyType : uint32_t { @@ -41,10 +41,10 @@ static typename std::enable_if::value, T>::type readInt(cons return *reinterpret_cast(data); } -// size of vertex key except vertexId +// size of tag key except vertexId static constexpr int32_t kTagLen = sizeof(PartitionID) + sizeof(TagID); -// size of vertex key except srcId and dstId +// size of tag key except srcId and dstId static constexpr int32_t kEdgeLen = sizeof(PartitionID) + sizeof(EdgeType) + sizeof(EdgeRanking) + sizeof(EdgeVerPlaceHolder); diff --git a/src/storage/CompactionFilter.h b/src/storage/CompactionFilter.h index 1c17b1d3ff4..9041ab47b9d 100644 --- a/src/storage/CompactionFilter.h +++ b/src/storage/CompactionFilter.h @@ -31,7 +31,7 @@ class StorageCompactionFilter final : public kvstore::KVFilter { const folly::StringPiece& key, const folly::StringPiece& val) const override { if (NebulaKeyUtils::isTag(vIdLen_, key)) { - return !vertexValid(spaceId, key, val); + return !tagValid(spaceId, key, val); } else if (NebulaKeyUtils::isEdge(vIdLen_, key)) { return !edgeValid(spaceId, key, val); } else if (IndexKeyUtils::isIndexKey(key)) { @@ -46,9 +46,9 @@ class StorageCompactionFilter final : public kvstore::KVFilter { } private: - bool vertexValid(GraphSpaceID spaceId, - const folly::StringPiece& key, - const folly::StringPiece& val) const { + bool tagValid(GraphSpaceID spaceId, + const folly::StringPiece& key, + const folly::StringPiece& val) const { auto tagId = NebulaKeyUtils::getTagId(vIdLen_, key); auto schema = schemaMan_->getTagSchema(spaceId, tagId); if (!schema) { diff --git a/src/storage/exec/GetPropNode.h b/src/storage/exec/GetPropNode.h index bacef34baa5..87b35c7e9b9 100644 --- a/src/storage/exec/GetPropNode.h +++ b/src/storage/exec/GetPropNode.h @@ -30,11 +30,19 @@ class GetTagPropNode : public QueryNode { return ret; } - // if none of the tag node valid, do not emplace the row + // if none of the tag node and vertex valid, do not emplace the row if (!std::any_of(tagNodes_.begin(), tagNodes_.end(), [](const auto& tagNode) { return tagNode->valid(); })) { - return nebula::cpp2::ErrorCode::SUCCEEDED; + auto kvstore = context_->env()->kvstore_; + auto vertexKey = NebulaKeyUtils::vertexKey(context_->vIdLen(), partId, vId); + std::string value; + ret = kvstore->get(context_->spaceId(), partId, vertexKey, &value); + if (ret == nebula::cpp2::ErrorCode::E_KEY_NOT_FOUND) { + return nebula::cpp2::ErrorCode::SUCCEEDED; + } else if (ret != nebula::cpp2::ErrorCode::SUCCEEDED) { + return ret; + } } List row; diff --git a/src/storage/exec/UpdateNode.h b/src/storage/exec/UpdateNode.h index 0b6e3abe36d..261cce227a0 100644 --- a/src/storage/exec/UpdateNode.h +++ b/src/storage/exec/UpdateNode.h @@ -412,6 +412,7 @@ class UpdateTagNode : public UpdateNode { } } // step 3, insert new vertex data + batchHolder->put(NebulaKeyUtils::vertexKey(context_->vIdLen(), partId, vId), ""); batchHolder->put(std::move(key_), std::move(nVal)); return encodeBatchValue(batchHolder->getBatch()); } diff --git a/src/storage/mutate/AddVerticesProcessor.cpp b/src/storage/mutate/AddVerticesProcessor.cpp index 2396014d841..055c4309538 100644 --- a/src/storage/mutate/AddVerticesProcessor.cpp +++ b/src/storage/mutate/AddVerticesProcessor.cpp @@ -78,7 +78,7 @@ void AddVerticesProcessor::doProcess(const cpp2::AddVerticesRequest& req) { code = nebula::cpp2::ErrorCode::E_INVALID_VID; break; } - + data.emplace_back(NebulaKeyUtils::vertexKey(spaceVidLen_, partId, vid), ""); for (auto& newTag : newTags) { auto tagId = newTag.get_tag_id(); VLOG(3) << "PartitionID: " << partId << ", VertexID: " << vid << ", TagID: " << tagId; @@ -155,7 +155,7 @@ void AddVerticesProcessor::doProcessWithIndex(const cpp2::AddVerticesRequest& re code = nebula::cpp2::ErrorCode::E_INVALID_VID; break; } - + batchHolder->put(NebulaKeyUtils::vertexKey(spaceVidLen_, partId, vid), ""); for (auto& newTag : newTags) { auto tagId = newTag.get_tag_id(); auto l = std::make_tuple(spaceId_, partId, tagId, vid); diff --git a/src/storage/mutate/DeleteVerticesProcessor.cpp b/src/storage/mutate/DeleteVerticesProcessor.cpp index e9a6bae1840..570cbb0672a 100644 --- a/src/storage/mutate/DeleteVerticesProcessor.cpp +++ b/src/storage/mutate/DeleteVerticesProcessor.cpp @@ -61,7 +61,7 @@ void DeleteVerticesProcessor::process(const cpp2::DeleteVerticesRequest& req) { code = nebula::cpp2::ErrorCode::E_INVALID_VID; break; } - + keys.emplace_back(NebulaKeyUtils::vertexKey(spaceVidLen_, partId, vid.getStr())); auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen_, partId, vid.getStr()); std::unique_ptr iter; code = env_->kvstore_->prefix(spaceId_, partId, prefix, &iter); @@ -112,6 +112,7 @@ ErrorOr DeleteVerticesProcessor::deleteVer target.reserve(vertices.size()); std::unique_ptr batchHolder = std::make_unique(); for (auto& vertex : vertices) { + batchHolder->remove(NebulaKeyUtils::vertexKey(spaceVidLen_, partId, vertex.getStr())); auto prefix = NebulaKeyUtils::tagPrefix(spaceVidLen_, partId, vertex.getStr()); std::unique_ptr iter; auto ret = env_->kvstore_->prefix(spaceId_, partId, prefix, &iter); diff --git a/tests/tck/features/delete/DeleteTag.IntVid.feature b/tests/tck/features/delete/DeleteTag.IntVid.feature index af279dd4701..aaffae4d825 100644 --- a/tests/tck/features/delete/DeleteTag.IntVid.feature +++ b/tests/tck/features/delete/DeleteTag.IntVid.feature @@ -41,6 +41,7 @@ Feature: Delete int vid of tag """ Then the result should be, in any order: | player.name | player.age | + | EMPTY | EMPTY | When executing query: """ FETCH PROP ON bachelor hash("Tim Duncan") YIELD bachelor.name, bachelor.speciality @@ -94,12 +95,14 @@ Feature: Delete int vid of tag """ Then the result should be, in any order: | player.name | player.age | + | EMPTY | EMPTY | When executing query: """ FETCH PROP ON bachelor hash("Tim Duncan") YIELD bachelor.name, bachelor.speciality """ Then the result should be, in any order: | bachelor.name | bachelor.speciality | + | EMPTY | EMPTY | When executing query: """ LOOKUP ON player WHERE player.name == "Tim Duncan" YIELD id(vertex) as id @@ -146,12 +149,14 @@ Feature: Delete int vid of tag """ Then the result should be, in any order: | player.name | player.age | + | EMPTY | EMPTY | When executing query: """ FETCH PROP ON bachelor hash("Tim Duncan") YIELD bachelor.name, bachelor.speciality """ Then the result should be, in any order: | bachelor.name | bachelor.speciality | + | EMPTY | EMPTY | When executing query: """ LOOKUP ON player WHERE player.name == "Tim Duncan" YIELD id(vertex) as id @@ -205,12 +210,14 @@ Feature: Delete int vid of tag """ Then the result should be, in any order: | player.name | player.age | + | EMPTY | EMPTY | When executing query: """ FETCH PROP ON player hash("Tony Parker") YIELD player.name, player.age """ Then the result should be, in any order: | player.name | player.age | + | EMPTY | EMPTY | When executing query: """ LOOKUP ON player WHERE player.name == "Tim Duncan" YIELD id(vertex) as id @@ -256,6 +263,7 @@ Feature: Delete int vid of tag """ Then the result should be, in any order: | team.name | + | EMPTY | # delete tag from pipe and normal When executing query: """ @@ -295,6 +303,7 @@ Feature: Delete int vid of tag """ Then the result should be, in any order: | team.name | + | EMPTY | # delete one tag from var and normal When executing query: """ diff --git a/tests/tck/features/delete/DeleteTag.feature b/tests/tck/features/delete/DeleteTag.feature index 4e01b0cdeff..5770bdcd133 100644 --- a/tests/tck/features/delete/DeleteTag.feature +++ b/tests/tck/features/delete/DeleteTag.feature @@ -41,6 +41,7 @@ Feature: Delete string vid of tag """ Then the result should be, in any order: | player.name | player.age | + | EMPTY | EMPTY | When executing query: """ FETCH PROP ON bachelor "Tim Duncan" YIELD bachelor.name, bachelor.speciality @@ -94,12 +95,14 @@ Feature: Delete string vid of tag """ Then the result should be, in any order: | player.name | player.age | + | EMPTY | EMPTY | When executing query: """ FETCH PROP ON bachelor "Tim Duncan" YIELD bachelor.name, bachelor.speciality """ Then the result should be, in any order: | bachelor.name | bachelor.speciality | + | EMPTY | EMPTY | When executing query: """ LOOKUP ON player WHERE player.name == "Tim Duncan" YIELD id(vertex) as id @@ -146,12 +149,14 @@ Feature: Delete string vid of tag """ Then the result should be, in any order: | player.name | player.age | + | EMPTY | EMPTY | When executing query: """ FETCH PROP ON bachelor "Tim Duncan" YIELD bachelor.name, bachelor.speciality """ Then the result should be, in any order: | bachelor.name | bachelor.speciality | + | EMPTY | EMPTY | When executing query: """ LOOKUP ON player WHERE player.name == "Tim Duncan" YIELD id(vertex) as id @@ -205,12 +210,14 @@ Feature: Delete string vid of tag """ Then the result should be, in any order: | player.name | player.age | + | EMPTY | EMPTY | When executing query: """ FETCH PROP ON player "Tony Parker" YIELD player.name, player.age """ Then the result should be, in any order: | player.name | player.age | + | EMPTY | EMPTY | When executing query: """ LOOKUP ON player WHERE player.name == "Tim Duncan" YIELD id(vertex) as id @@ -256,6 +263,7 @@ Feature: Delete string vid of tag """ Then the result should be, in any order: | team.name | + | EMPTY | # delete tag from pipe and normal When executing query: """ @@ -295,6 +303,7 @@ Feature: Delete string vid of tag """ Then the result should be, in any order: | team.name | + | EMPTY | # delete one tag from var and normal When executing query: """ diff --git a/tests/tck/features/ttl/TTL.feature b/tests/tck/features/ttl/TTL.feature index 1cb456d209d..f3f74c6c618 100644 --- a/tests/tck/features/ttl/TTL.feature +++ b/tests/tck/features/ttl/TTL.feature @@ -393,31 +393,36 @@ Feature: TTLTest FETCH PROP ON person "1" YIELD vertex as node; """ Then the result should be, in any order, with relax comparison: - | node | + | node | + | ("1") | When executing query: """ FETCH PROP ON person "1" YIELD person.id as id """ Then the result should be, in any order: - | id | + | id | + | EMPTY | When executing query: """ FETCH PROP ON * "1" YIELD person.id, career.id """ Then the result should be, in any order: | person.id | career.id | + | EMPTY | EMPTY | When executing query: """ FETCH PROP ON person "2" YIELD person.id """ Then the result should be, in any order: | person.id | + | EMPTY | When executing query: """ FETCH PROP ON person "2" YIELD person.id as id """ Then the result should be, in any order: - | id | + | id | + | EMPTY | When executing query: """ FETCH PROP ON career "2" YIELD career.id; @@ -486,5 +491,6 @@ Feature: TTLTest FETCH PROP ON person "1" YIELD person.age as age; """ Then the result should be, in any order: - | age | + | age | + | EMPTY | And drop the used space