Implement existence constraints

Reviewers: teon.banek, mferencevic

Reviewed By: teon.banek, mferencevic

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D2307
This commit is contained in:
Marin Tomic 2019-08-20 14:59:13 +02:00
parent b8e964a82d
commit 1ab0b8e0ff
9 changed files with 413 additions and 125 deletions

View File

@ -0,0 +1,75 @@
#pragma once
#include <optional>
#include <vector>
#include "storage/v2/id_types.hpp"
#include "storage/v2/vertex.hpp"
#include "utils/result.hpp"
#include "utils/skip_list.hpp"
namespace storage {
struct Constraints {
std::vector<std::pair<LabelId, PropertyId>> existence_constraints;
};
struct ExistenceConstraintViolation {
LabelId label;
PropertyId property;
};
/// Adds a unique constraint to `constraints`. Returns true if the constraint
/// was successfuly added, false if it already exists and an
/// `ExistenceConstraintViolation` if there is an existing vertex violating the
/// constraint.
///
/// @throw std::bad_alloc
/// @throw std::length_error
inline utils::BasicResult<ExistenceConstraintViolation, bool>
CreateExistenceConstraint(Constraints *constraints, LabelId label,
PropertyId property,
utils::SkipList<Vertex>::Accessor vertices) {
if (utils::Contains(constraints->existence_constraints,
std::make_pair(label, property))) {
return false;
}
for (const auto &vertex : vertices) {
if (!vertex.deleted && utils::Contains(vertex.labels, label) &&
vertex.properties.find(property) == vertex.properties.end()) {
return ExistenceConstraintViolation{label, property};
}
}
constraints->existence_constraints.emplace_back(label, property);
return true;
}
/// Removes a unique constraint from `constraints`. Returns true if the
/// constraint was removed, and false if it doesn't exist.
inline bool DropExistenceConstraint(Constraints *constraints, LabelId label,
PropertyId property) {
auto it = std::find(constraints->existence_constraints.begin(),
constraints->existence_constraints.end(),
std::make_pair(label, property));
if (it == constraints->existence_constraints.end()) {
return false;
}
constraints->existence_constraints.erase(it);
return true;
}
/// Verifies that the given vertex satisfies all existence constraints. Returns
/// nullopt if all checks pass, and `ExistenceConstraintViolation` describing
/// the violated constraint otherwise.
[[nodiscard]] inline std::optional<ExistenceConstraintViolation>
ValidateExistenceConstraints(Vertex *vertex, Constraints *constraints) {
for (const auto &[label, property] : constraints->existence_constraints) {
if (!vertex->deleted && utils::Contains(vertex->labels, label) &&
vertex->properties.find(property) == vertex->properties.end()) {
return ExistenceConstraintViolation{label, property};
}
}
return std::nullopt;
}
} // namespace storage

View File

@ -580,7 +580,8 @@ EdgeTypeId Storage::Accessor::NameToEdgeType(const std::string &name) {
void Storage::Accessor::AdvanceCommand() { ++transaction_.command_id; }
void Storage::Accessor::Commit() {
[[nodiscard]] std::optional<ExistenceConstraintViolation>
Storage::Accessor::Commit() {
CHECK(is_transaction_active_) << "The transaction is already terminated!";
CHECK(!transaction_.must_abort) << "The transaction can't be committed!";
@ -589,6 +590,23 @@ void Storage::Accessor::Commit() {
// it.
storage_->commit_log_.MarkFinished(transaction_.start_timestamp);
} else {
// Validate that existence constraints are satisfied for all modified
// vertices.
for (const auto &delta : transaction_.deltas) {
auto prev = delta.prev.Get();
if (prev.type != PreviousPtr::Type::VERTEX) {
continue;
}
// No need to take any locks here because we modified this vertex and no
// one else can touch it until we commit.
auto validation_result =
ValidateExistenceConstraints(prev.vertex, &storage_->constraints_);
if (validation_result) {
Abort();
return *validation_result;
}
}
// Save these so we can mark them used in the commit log.
uint64_t start_timestamp = transaction_.start_timestamp;
uint64_t commit_timestamp;
@ -622,6 +640,8 @@ void Storage::Accessor::Commit() {
if (storage_->gc_config_.type == StorageGcConfig::Type::ON_FINISH) {
storage_->CollectGarbage();
}
return std::nullopt;
}
void Storage::Accessor::Abort() {

View File

@ -4,6 +4,7 @@
#include <shared_mutex>
#include "storage/v2/commit_log.hpp"
#include "storage/v2/constraints.hpp"
#include "storage/v2/edge.hpp"
#include "storage/v2/edge_accessor.hpp"
#include "storage/v2/indices.hpp"
@ -215,7 +216,10 @@ class Storage final {
void AdvanceCommand();
void Commit();
/// Commit returns `ExistenceConstraintViolation` if the changes made by
/// this transaction violate an existence constraint. In that case the
/// transaction is automatically aborted. Otherwise, nullopt is returned.
[[nodiscard]] std::optional<ExistenceConstraintViolation> Commit();
void Abort();
@ -252,15 +256,36 @@ class Storage final {
return indices_.label_property_index.IndexExists(label, property);
}
/// Creates a unique constraint`. Returns true if the constraint was
/// successfuly added, false if it already exists and an
/// `ExistenceConstraintViolation` if there is an existing vertex violating
/// the constraint.
///
/// @throw std::bad_alloc
/// @throw std::length_error
utils::BasicResult<ExistenceConstraintViolation, bool>
CreateExistenceConstraint(LabelId label, PropertyId property) {
std::unique_lock<utils::RWLock> storage_guard(main_lock_);
return ::storage::CreateExistenceConstraint(&constraints_, label, property,
vertices_.access());
}
/// Removes a unique constraint. Returns true if the constraint was removed,
/// and false if it doesn't exist.
bool DropExistenceConstraint(LabelId label, PropertyId property) {
std::unique_lock<utils::RWLock> storage_guard(main_lock_);
return ::storage::DropExistenceConstraint(&constraints_, label, property);
}
private:
void CollectGarbage();
// Main storage lock.
//
// Accessors take a shared lock when starting, so it is possible to block
// creation of new accessors by taking a unique lock. This is used when
// building a label-property index because it is much simpler to do when there
// are no parallel reads and writes.
// creation of new accessors by taking a unique lock. This is used when doing
// operations on storage that affect the global state, for example index
// creation.
utils::RWLock main_lock_{utils::RWLock::Priority::WRITE};
// Main object storage
@ -272,6 +297,7 @@ class Storage final {
NameIdMapper name_id_mapper_;
Indices indices_;
Constraints constraints_;
// Transaction engine
utils::SpinLock engine_lock_;

View File

@ -43,7 +43,7 @@ void UpdateLabelFunc(int thread_id, storage::Storage *storage,
<< "Vertex with GID " << gid.AsUint() << " doesn't exist";
if (vertex->AddLabel(storage::LabelId::FromUint(label_dist(gen)))
.HasValue()) {
acc.Commit();
CHECK(acc.Commit() == std::nullopt);
} else {
acc.Abort();
}
@ -61,7 +61,7 @@ int main(int argc, char *argv[]) {
for (int i = 0; i < FLAGS_num_vertices; ++i) {
vertices.push_back(acc.CreateVertex().Gid());
}
acc.Commit();
CHECK(acc.Commit() == std::nullopt);
}
utils::Timer timer;

View File

@ -310,6 +310,9 @@ target_link_libraries(${test_prefix}auth mg-auth kvstore_lib)
add_unit_test(property_value_v2.cpp)
target_link_libraries(${test_prefix}property_value_v2 mg-utils)
add_unit_test(storage_v2_constraints.cpp)
target_link_libraries(${test_prefix}storage_v2_constraints mg-storage-v2)
add_unit_test(storage_v2_edge.cpp)
target_link_libraries(${test_prefix}storage_v2_edge mg-storage-v2)

View File

@ -25,7 +25,7 @@ TEST(StorageV2, Commit) {
EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U);
ASSERT_TRUE(acc.FindVertex(gid, storage::View::NEW).has_value());
EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 1U);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
{
auto acc = store.Access();
@ -45,7 +45,7 @@ TEST(StorageV2, Commit) {
EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 1U);
EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 0U);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
{
auto acc = store.Access();
@ -111,7 +111,7 @@ TEST(StorageV2, AdvanceCommandCommit) {
ASSERT_TRUE(acc.FindVertex(gid1, storage::View::OLD).has_value());
ASSERT_TRUE(acc.FindVertex(gid1, storage::View::NEW).has_value());
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
{
auto acc = store.Access();
@ -185,7 +185,7 @@ TEST(StorageV2, SnapshotIsolation) {
EXPECT_EQ(CountVertices(&acc1, storage::View::NEW), 1U);
EXPECT_EQ(CountVertices(&acc2, storage::View::NEW), 0U);
acc1.Commit();
ASSERT_EQ(acc1.Commit(), std::nullopt);
ASSERT_FALSE(acc2.FindVertex(gid, storage::View::OLD).has_value());
EXPECT_EQ(CountVertices(&acc2, storage::View::OLD), 0U);
@ -224,7 +224,7 @@ TEST(StorageV2, AccessorMove) {
ASSERT_TRUE(moved.FindVertex(gid, storage::View::NEW).has_value());
EXPECT_EQ(CountVertices(&moved, storage::View::NEW), 1U);
moved.Commit();
ASSERT_EQ(moved.Commit(), std::nullopt);
}
{
auto acc = store.Access();
@ -253,7 +253,7 @@ TEST(StorageV2, VertexDeleteCommit) {
EXPECT_EQ(CountVertices(&acc2, storage::View::OLD), 0U);
ASSERT_TRUE(acc2.FindVertex(gid, storage::View::NEW).has_value());
EXPECT_EQ(CountVertices(&acc2, storage::View::NEW), 1U);
acc2.Commit();
ASSERT_EQ(acc2.Commit(), std::nullopt);
}
auto acc3 = store.Access(); // read transaction
@ -283,7 +283,7 @@ TEST(StorageV2, VertexDeleteCommit) {
EXPECT_EQ(CountVertices(&acc4, storage::View::OLD), 1U);
EXPECT_EQ(CountVertices(&acc4, storage::View::NEW), 0U);
acc4.Commit();
ASSERT_EQ(acc4.Commit(), std::nullopt);
}
auto acc5 = store.Access(); // read transaction
@ -324,7 +324,7 @@ TEST(StorageV2, VertexDeleteAbort) {
EXPECT_EQ(CountVertices(&acc2, storage::View::OLD), 0U);
ASSERT_TRUE(acc2.FindVertex(gid, storage::View::NEW).has_value());
EXPECT_EQ(CountVertices(&acc2, storage::View::NEW), 1U);
acc2.Commit();
ASSERT_EQ(acc2.Commit(), std::nullopt);
}
auto acc3 = store.Access(); // read transaction
@ -390,7 +390,7 @@ TEST(StorageV2, VertexDeleteAbort) {
EXPECT_EQ(CountVertices(&acc6, storage::View::OLD), 1U);
EXPECT_EQ(CountVertices(&acc6, storage::View::NEW), 0U);
acc6.Commit();
ASSERT_EQ(acc6.Commit(), std::nullopt);
}
auto acc7 = store.Access(); // read transaction
@ -420,10 +420,10 @@ TEST(StorageV2, VertexDeleteAbort) {
EXPECT_EQ(CountVertices(&acc7, storage::View::NEW), 0U);
// Commit all accessors
acc1.Commit();
acc3.Commit();
acc5.Commit();
acc7.Commit();
ASSERT_EQ(acc1.Commit(), std::nullopt);
ASSERT_EQ(acc3.Commit(), std::nullopt);
ASSERT_EQ(acc5.Commit(), std::nullopt);
ASSERT_EQ(acc7.Commit(), std::nullopt);
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
@ -437,7 +437,7 @@ TEST(StorageV2, VertexDeleteSerializationError) {
auto acc = store.Access();
auto vertex = acc.CreateVertex();
gid = vertex.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
auto acc1 = store.Access();
@ -481,7 +481,7 @@ TEST(StorageV2, VertexDeleteSerializationError) {
}
// Finalize both accessors
acc1.Commit();
ASSERT_EQ(acc1.Commit(), std::nullopt);
acc2.Abort();
// Check whether the vertex exists
@ -491,7 +491,7 @@ TEST(StorageV2, VertexDeleteSerializationError) {
ASSERT_FALSE(vertex);
EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U);
EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 0U);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -535,7 +535,7 @@ TEST(StorageV2, VertexDeleteSpecialCases) {
ASSERT_TRUE(res.GetValue());
EXPECT_EQ(CountVertices(&acc, storage::View::OLD), 0U);
EXPECT_EQ(CountVertices(&acc, storage::View::NEW), 0U);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the vertices exist
@ -564,7 +564,7 @@ TEST(StorageV2, VertexDeleteLabel) {
gid = vertex.Gid();
ASSERT_FALSE(acc.FindVertex(gid, storage::View::OLD).has_value());
ASSERT_TRUE(acc.FindVertex(gid, storage::View::NEW).has_value());
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Add label, delete the vertex and check the label API (same command)
@ -725,7 +725,7 @@ TEST(StorageV2, VertexDeleteProperty) {
gid = vertex.Gid();
ASSERT_FALSE(acc.FindVertex(gid, storage::View::OLD).has_value());
ASSERT_TRUE(acc.FindVertex(gid, storage::View::NEW).has_value());
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Set property, delete the vertex and check the property API (same command)
@ -743,9 +743,8 @@ TEST(StorageV2, VertexDeleteProperty) {
ASSERT_EQ(vertex->Properties(storage::View::NEW)->size(), 0);
// Set property 5 to "nandare"
ASSERT_TRUE(
vertex->SetProperty(property, storage::PropertyValue("nandare"))
.GetValue());
ASSERT_TRUE(vertex->SetProperty(property, storage::PropertyValue("nandare"))
.GetValue());
// Check whether property 5 exists
ASSERT_TRUE(vertex->GetProperty(property, storage::View::OLD)->IsNull());
@ -796,9 +795,8 @@ TEST(StorageV2, VertexDeleteProperty) {
ASSERT_EQ(vertex->Properties(storage::View::NEW)->size(), 0);
// Set property 5 to "nandare"
ASSERT_TRUE(
vertex->SetProperty(property, storage::PropertyValue("nandare"))
.GetValue());
ASSERT_TRUE(vertex->SetProperty(property, storage::PropertyValue("nandare"))
.GetValue());
// Check whether property 5 exists
ASSERT_TRUE(vertex->GetProperty(property, storage::View::OLD)->IsNull());
@ -905,7 +903,7 @@ TEST(StorageV2, VertexLabelCommit) {
ASSERT_FALSE(res.GetValue());
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
{
auto acc = store.Access();
@ -964,7 +962,7 @@ TEST(StorageV2, VertexLabelCommit) {
ASSERT_FALSE(res.GetValue());
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
{
auto acc = store.Access();
@ -998,7 +996,7 @@ TEST(StorageV2, VertexLabelAbort) {
auto acc = store.Access();
auto vertex = acc.CreateVertex();
gid = vertex.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Add label 5, but abort the transaction.
@ -1085,7 +1083,7 @@ TEST(StorageV2, VertexLabelAbort) {
ASSERT_FALSE(res.GetValue());
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check that label 5 exists.
@ -1211,7 +1209,7 @@ TEST(StorageV2, VertexLabelAbort) {
ASSERT_FALSE(res.GetValue());
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check that label 5 doesn't exist.
@ -1245,7 +1243,7 @@ TEST(StorageV2, VertexLabelSerializationError) {
auto acc = store.Access();
auto vertex = acc.CreateVertex();
gid = vertex.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
auto acc1 = store.Access();
@ -1313,7 +1311,7 @@ TEST(StorageV2, VertexLabelSerializationError) {
}
// Finalize both accessors.
acc1.Commit();
ASSERT_EQ(acc1.Commit(), std::nullopt);
acc2.Abort();
// Check which labels exist.
@ -1390,7 +1388,7 @@ TEST(StorageV2, VertexPropertyCommit) {
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
{
auto acc = store.Access();
@ -1454,7 +1452,7 @@ TEST(StorageV2, VertexPropertyCommit) {
ASSERT_TRUE(res.GetValue());
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
{
auto acc = store.Access();
@ -1490,7 +1488,7 @@ TEST(StorageV2, VertexPropertyAbort) {
auto acc = store.Access();
auto vertex = acc.CreateVertex();
gid = vertex.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Set property 5 to "nandare", but abort the transaction.
@ -1601,7 +1599,7 @@ TEST(StorageV2, VertexPropertyAbort) {
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check that property 5 is "nandare".
@ -1757,7 +1755,7 @@ TEST(StorageV2, VertexPropertyAbort) {
ASSERT_TRUE(vertex->GetProperty(property, storage::View::NEW)->IsNull());
ASSERT_EQ(vertex->Properties(storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check that property 5 is null.
@ -1793,7 +1791,7 @@ TEST(StorageV2, VertexPropertySerializationError) {
auto acc = store.Access();
auto vertex = acc.CreateVertex();
gid = vertex.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
auto acc1 = store.Access();
@ -1857,7 +1855,7 @@ TEST(StorageV2, VertexPropertySerializationError) {
}
// Finalize both accessors.
acc1.Commit();
ASSERT_EQ(acc1.Commit(), std::nullopt);
acc2.Abort();
// Check which properties exist.
@ -1942,7 +1940,7 @@ TEST(StorageV2, VertexLabelPropertyMixed) {
// Set property 5 to "nandare"
ASSERT_TRUE(vertex.SetProperty(property, storage::PropertyValue("nandare"))
.GetValue());
.GetValue());
// Check whether label 5 and property 5 exist
ASSERT_TRUE(vertex.HasLabel(label, storage::View::OLD).GetValue());
@ -2000,7 +1998,7 @@ TEST(StorageV2, VertexLabelPropertyMixed) {
// Set property 5 to "haihai"
ASSERT_FALSE(vertex.SetProperty(property, storage::PropertyValue("haihai"))
.GetValue());
.GetValue());
// Check whether label 5 and property 5 exist
ASSERT_TRUE(vertex.HasLabel(label, storage::View::OLD).GetValue());
@ -2143,5 +2141,5 @@ TEST(StorageV2, VertexLabelPropertyMixed) {
ASSERT_EQ(vertex.Properties(storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex.Properties(storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}

View File

@ -0,0 +1,166 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "storage/v2/storage.hpp"
// NOLINTNEXTLINE(google-build-using-namespace)
using namespace storage;
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define ASSERT_NO_ERROR(result) ASSERT_FALSE((result).HasError())
bool operator==(const ExistenceConstraintViolation &lhs,
const ExistenceConstraintViolation &rhs) {
return lhs.label == rhs.label && lhs.property == rhs.property;
}
class ConstraintsTest : public testing::Test {
protected:
ConstraintsTest()
: prop1(storage.NameToProperty("prop1")),
prop2(storage.NameToProperty("prop2")),
label1(storage.NameToLabel("label1")),
label2(storage.NameToLabel("label2")) {}
Storage storage;
PropertyId prop1;
PropertyId prop2;
LabelId label1;
LabelId label2;
};
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_F(ConstraintsTest, CreateAndDrop) {
{
auto res = storage.CreateExistenceConstraint(label1, prop1);
EXPECT_TRUE(res.HasValue() && res.GetValue());
}
{
auto res = storage.CreateExistenceConstraint(label1, prop1);
EXPECT_TRUE(res.HasValue() && !res.GetValue());
}
{
auto res = storage.CreateExistenceConstraint(label2, prop1);
EXPECT_TRUE(res.HasValue() && res.GetValue());
}
EXPECT_TRUE(storage.DropExistenceConstraint(label1, prop1));
EXPECT_FALSE(storage.DropExistenceConstraint(label1, prop1));
EXPECT_TRUE(storage.DropExistenceConstraint(label2, prop1));
EXPECT_FALSE(storage.DropExistenceConstraint(label2, prop2));
{
auto res = storage.CreateExistenceConstraint(label2, prop1);
EXPECT_TRUE(res.HasValue() && res.GetValue());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_F(ConstraintsTest, CreateFailure1) {
{
auto acc = storage.Access();
auto vertex = acc.CreateVertex();
ASSERT_NO_ERROR(vertex.AddLabel(label1));
ASSERT_EQ(acc.Commit(), std::nullopt);
}
{
auto res = storage.CreateExistenceConstraint(label1, prop1);
EXPECT_TRUE(
res.HasError() &&
(res.GetError() == ExistenceConstraintViolation{label1, prop1}));
}
{
auto acc = storage.Access();
for (auto vertex : acc.Vertices(View::OLD)) {
ASSERT_NO_ERROR(acc.DeleteVertex(&vertex));
}
ASSERT_EQ(acc.Commit(), std::nullopt);
}
{
auto res = storage.CreateExistenceConstraint(label1, prop1);
EXPECT_TRUE(res.HasValue() && res.GetValue());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_F(ConstraintsTest, CreateFailure2) {
{
auto acc = storage.Access();
auto vertex = acc.CreateVertex();
ASSERT_NO_ERROR(vertex.AddLabel(label1));
ASSERT_EQ(acc.Commit(), std::nullopt);
}
{
auto res = storage.CreateExistenceConstraint(label1, prop1);
EXPECT_TRUE(
res.HasError() &&
(res.GetError() == ExistenceConstraintViolation{label1, prop1}));
}
{
auto acc = storage.Access();
for (auto vertex : acc.Vertices(View::OLD)) {
ASSERT_NO_ERROR(vertex.SetProperty(prop1, PropertyValue(1)));
}
ASSERT_EQ(acc.Commit(), std::nullopt);
}
{
auto res = storage.CreateExistenceConstraint(label1, prop1);
EXPECT_TRUE(res.HasValue() && res.GetValue());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_F(ConstraintsTest, ViolationOnCommit) {
{
auto res = storage.CreateExistenceConstraint(label1, prop1);
ASSERT_TRUE(res.HasValue() && res.GetValue());
}
{
auto acc = storage.Access();
auto vertex = acc.CreateVertex();
ASSERT_NO_ERROR(vertex.AddLabel(label1));
auto res = acc.Commit();
EXPECT_TRUE(res.has_value() &&
(*res == ExistenceConstraintViolation{label1, prop1}));
}
{
auto acc = storage.Access();
auto vertex = acc.CreateVertex();
ASSERT_NO_ERROR(vertex.AddLabel(label1));
ASSERT_NO_ERROR(vertex.SetProperty(prop1, PropertyValue(1)));
EXPECT_EQ(acc.Commit(), std::nullopt);
}
{
auto acc = storage.Access();
for (auto vertex : acc.Vertices(View::OLD)) {
ASSERT_NO_ERROR(vertex.SetProperty(prop1, PropertyValue()));
}
auto res = acc.Commit();
EXPECT_TRUE(res.has_value() &&
(*res == ExistenceConstraintViolation{label1, prop1}));
}
{
auto acc = storage.Access();
for (auto vertex : acc.Vertices(View::OLD)) {
ASSERT_NO_ERROR(vertex.SetProperty(prop1, PropertyValue()));
}
for (auto vertex : acc.Vertices(View::OLD)) {
ASSERT_NO_ERROR(acc.DeleteVertex(&vertex));
}
EXPECT_EQ(acc.Commit(), std::nullopt);
}
ASSERT_TRUE(storage.DropExistenceConstraint(label1, prop1));
{
auto acc = storage.Access();
auto vertex = acc.CreateVertex();
ASSERT_NO_ERROR(vertex.AddLabel(label1));
EXPECT_EQ(acc.Commit(), std::nullopt);
}
}

View File

@ -19,7 +19,7 @@ TEST(StorageV2, EdgeCreateFromSmallerCommit) {
auto vertex_to = acc.CreateVertex();
gid_from = vertex_from.Gid();
gid_to = vertex_to.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge
@ -77,7 +77,7 @@ TEST(StorageV2, EdgeCreateFromSmallerCommit) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -152,7 +152,7 @@ TEST(StorageV2, EdgeCreateFromSmallerCommit) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -171,7 +171,7 @@ TEST(StorageV2, EdgeCreateFromLargerCommit) {
auto vertex_from = acc.CreateVertex();
gid_to = vertex_to.Gid();
gid_from = vertex_from.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge
@ -229,7 +229,7 @@ TEST(StorageV2, EdgeCreateFromLargerCommit) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -304,7 +304,7 @@ TEST(StorageV2, EdgeCreateFromLargerCommit) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -319,7 +319,7 @@ TEST(StorageV2, EdgeCreateFromSameCommit) {
auto acc = store.Access();
auto vertex = acc.CreateVertex();
gid_vertex = vertex.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge
@ -369,7 +369,7 @@ TEST(StorageV2, EdgeCreateFromSameCommit) {
ASSERT_EQ(vertex->InEdges({other_et}, storage::View::NEW)->size(), 0);
ASSERT_EQ(vertex->InEdges({et, other_et}, storage::View::NEW)->size(), 1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -434,7 +434,7 @@ TEST(StorageV2, EdgeCreateFromSameCommit) {
ASSERT_EQ(vertex->OutEdges({et, other_et}, storage::View::OLD)->size(), 1);
ASSERT_EQ(vertex->OutEdges({et, other_et}, storage::View::NEW)->size(), 1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -453,7 +453,7 @@ TEST(StorageV2, EdgeCreateFromSmallerAbort) {
auto vertex_to = acc.CreateVertex();
gid_from = vertex_from.Gid();
gid_to = vertex_to.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge, but abort the transaction
@ -532,7 +532,7 @@ TEST(StorageV2, EdgeCreateFromSmallerAbort) {
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge
@ -590,7 +590,7 @@ TEST(StorageV2, EdgeCreateFromSmallerAbort) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -665,7 +665,7 @@ TEST(StorageV2, EdgeCreateFromSmallerAbort) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -684,7 +684,7 @@ TEST(StorageV2, EdgeCreateFromLargerAbort) {
auto vertex_from = acc.CreateVertex();
gid_to = vertex_to.Gid();
gid_from = vertex_from.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge, but abort the transaction
@ -763,7 +763,7 @@ TEST(StorageV2, EdgeCreateFromLargerAbort) {
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge
@ -821,7 +821,7 @@ TEST(StorageV2, EdgeCreateFromLargerAbort) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -896,7 +896,7 @@ TEST(StorageV2, EdgeCreateFromLargerAbort) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -911,7 +911,7 @@ TEST(StorageV2, EdgeCreateFromSameAbort) {
auto acc = store.Access();
auto vertex = acc.CreateVertex();
gid_vertex = vertex.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge, but abort the transaction
@ -976,7 +976,7 @@ TEST(StorageV2, EdgeCreateFromSameAbort) {
ASSERT_EQ(vertex->OutEdges({}, storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex->OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge
@ -1026,7 +1026,7 @@ TEST(StorageV2, EdgeCreateFromSameAbort) {
ASSERT_EQ(vertex->InEdges({other_et}, storage::View::NEW)->size(), 0);
ASSERT_EQ(vertex->InEdges({et, other_et}, storage::View::NEW)->size(), 1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -1091,7 +1091,7 @@ TEST(StorageV2, EdgeCreateFromSameAbort) {
ASSERT_EQ(vertex->OutEdges({et, other_et}, storage::View::OLD)->size(), 1);
ASSERT_EQ(vertex->OutEdges({et, other_et}, storage::View::NEW)->size(), 1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -1110,7 +1110,7 @@ TEST(StorageV2, EdgeDeleteFromSmallerCommit) {
auto vertex_to = acc.CreateVertex();
gid_from = vertex_from.Gid();
gid_to = vertex_to.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge
@ -1168,7 +1168,7 @@ TEST(StorageV2, EdgeDeleteFromSmallerCommit) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -1243,7 +1243,7 @@ TEST(StorageV2, EdgeDeleteFromSmallerCommit) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Delete edge
@ -1300,7 +1300,7 @@ TEST(StorageV2, EdgeDeleteFromSmallerCommit) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::OLD)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -1321,7 +1321,7 @@ TEST(StorageV2, EdgeDeleteFromSmallerCommit) {
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -1340,7 +1340,7 @@ TEST(StorageV2, EdgeDeleteFromLargerCommit) {
auto vertex_from = acc.CreateVertex();
gid_from = vertex_from.Gid();
gid_to = vertex_to.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge
@ -1398,7 +1398,7 @@ TEST(StorageV2, EdgeDeleteFromLargerCommit) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -1473,7 +1473,7 @@ TEST(StorageV2, EdgeDeleteFromLargerCommit) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Delete edge
@ -1530,7 +1530,7 @@ TEST(StorageV2, EdgeDeleteFromLargerCommit) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::OLD)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -1551,7 +1551,7 @@ TEST(StorageV2, EdgeDeleteFromLargerCommit) {
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -1566,7 +1566,7 @@ TEST(StorageV2, EdgeDeleteFromSameCommit) {
auto acc = store.Access();
auto vertex = acc.CreateVertex();
gid_vertex = vertex.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge
@ -1616,7 +1616,7 @@ TEST(StorageV2, EdgeDeleteFromSameCommit) {
ASSERT_EQ(vertex->InEdges({other_et}, storage::View::NEW)->size(), 0);
ASSERT_EQ(vertex->InEdges({et, other_et}, storage::View::NEW)->size(), 1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -1681,7 +1681,7 @@ TEST(StorageV2, EdgeDeleteFromSameCommit) {
ASSERT_EQ(vertex->OutEdges({et, other_et}, storage::View::OLD)->size(), 1);
ASSERT_EQ(vertex->OutEdges({et, other_et}, storage::View::NEW)->size(), 1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Delete edge
@ -1730,7 +1730,7 @@ TEST(StorageV2, EdgeDeleteFromSameCommit) {
ASSERT_EQ(vertex->OutEdges({other_et}, storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex->OutEdges({et, other_et}, storage::View::OLD)->size(), 1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -1745,7 +1745,7 @@ TEST(StorageV2, EdgeDeleteFromSameCommit) {
ASSERT_EQ(vertex->OutEdges({}, storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex->OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -1764,7 +1764,7 @@ TEST(StorageV2, EdgeDeleteFromSmallerAbort) {
auto vertex_to = acc.CreateVertex();
gid_from = vertex_from.Gid();
gid_to = vertex_to.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge
@ -1822,7 +1822,7 @@ TEST(StorageV2, EdgeDeleteFromSmallerAbort) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -1897,7 +1897,7 @@ TEST(StorageV2, EdgeDeleteFromSmallerAbort) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Delete the edge, but abort the transaction
@ -2029,7 +2029,7 @@ TEST(StorageV2, EdgeDeleteFromSmallerAbort) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Delete the edge
@ -2086,7 +2086,7 @@ TEST(StorageV2, EdgeDeleteFromSmallerAbort) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::OLD)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -2107,7 +2107,7 @@ TEST(StorageV2, EdgeDeleteFromSmallerAbort) {
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -2126,7 +2126,7 @@ TEST(StorageV2, EdgeDeleteFromLargerAbort) {
auto vertex_to = acc.CreateVertex();
gid_from = vertex_from.Gid();
gid_to = vertex_to.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge
@ -2184,7 +2184,7 @@ TEST(StorageV2, EdgeDeleteFromLargerAbort) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -2259,7 +2259,7 @@ TEST(StorageV2, EdgeDeleteFromLargerAbort) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Delete the edge, but abort the transaction
@ -2391,7 +2391,7 @@ TEST(StorageV2, EdgeDeleteFromLargerAbort) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::NEW)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Delete the edge
@ -2448,7 +2448,7 @@ TEST(StorageV2, EdgeDeleteFromLargerAbort) {
ASSERT_EQ(vertex_to->InEdges({et, other_et}, storage::View::OLD)->size(),
1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -2469,7 +2469,7 @@ TEST(StorageV2, EdgeDeleteFromLargerAbort) {
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -2484,7 +2484,7 @@ TEST(StorageV2, EdgeDeleteFromSameAbort) {
auto acc = store.Access();
auto vertex = acc.CreateVertex();
gid_vertex = vertex.Gid();
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Create edge
@ -2534,7 +2534,7 @@ TEST(StorageV2, EdgeDeleteFromSameAbort) {
ASSERT_EQ(vertex->InEdges({other_et}, storage::View::NEW)->size(), 0);
ASSERT_EQ(vertex->InEdges({et, other_et}, storage::View::NEW)->size(), 1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -2599,7 +2599,7 @@ TEST(StorageV2, EdgeDeleteFromSameAbort) {
ASSERT_EQ(vertex->OutEdges({et, other_et}, storage::View::OLD)->size(), 1);
ASSERT_EQ(vertex->OutEdges({et, other_et}, storage::View::NEW)->size(), 1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Delete the edge, but abort the transaction
@ -2713,7 +2713,7 @@ TEST(StorageV2, EdgeDeleteFromSameAbort) {
ASSERT_EQ(vertex->OutEdges({et, other_et}, storage::View::OLD)->size(), 1);
ASSERT_EQ(vertex->OutEdges({et, other_et}, storage::View::NEW)->size(), 1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Delete the edge
@ -2762,7 +2762,7 @@ TEST(StorageV2, EdgeDeleteFromSameAbort) {
ASSERT_EQ(vertex->OutEdges({other_et}, storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex->OutEdges({et, other_et}, storage::View::OLD)->size(), 1);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check whether the edge exists
@ -2777,7 +2777,7 @@ TEST(StorageV2, EdgeDeleteFromSameAbort) {
ASSERT_EQ(vertex->OutEdges({}, storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex->OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -2831,7 +2831,7 @@ TEST(StorageV2, VertexDetachDeleteSingleCommit) {
}
ASSERT_EQ(vertex_to.OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Detach delete vertex
@ -2888,7 +2888,7 @@ TEST(StorageV2, VertexDetachDeleteSingleCommit) {
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check dataset
@ -3043,7 +3043,7 @@ TEST(StorageV2, VertexDetachDeleteMultipleCommit) {
}
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Detach delete vertex
@ -3183,7 +3183,7 @@ TEST(StorageV2, VertexDetachDeleteMultipleCommit) {
ASSERT_EQ(e.ToVertex(), *vertex2);
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check dataset
@ -3290,7 +3290,7 @@ TEST(StorageV2, VertexDetachDeleteSingleAbort) {
}
ASSERT_EQ(vertex_to.OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Detach delete vertex, but abort the transaction
@ -3384,7 +3384,7 @@ TEST(StorageV2, VertexDetachDeleteSingleAbort) {
}
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Detach delete vertex
@ -3441,7 +3441,7 @@ TEST(StorageV2, VertexDetachDeleteSingleAbort) {
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::OLD)->size(), 0);
ASSERT_EQ(vertex_to->OutEdges({}, storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check dataset
@ -3596,7 +3596,7 @@ TEST(StorageV2, VertexDetachDeleteMultipleAbort) {
}
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Detach delete vertex, but abort the transaction
@ -3922,7 +3922,7 @@ TEST(StorageV2, VertexDetachDeleteMultipleAbort) {
}
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Detach delete vertex
@ -4062,7 +4062,7 @@ TEST(StorageV2, VertexDetachDeleteMultipleAbort) {
ASSERT_EQ(e.ToVertex(), *vertex2);
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check dataset
@ -4168,7 +4168,7 @@ TEST(StorageV2, EdgePropertyCommit) {
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
{
auto acc = store.Access();
@ -4232,7 +4232,7 @@ TEST(StorageV2, EdgePropertyCommit) {
ASSERT_TRUE(res.GetValue());
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
{
auto acc = store.Access();
@ -4272,7 +4272,7 @@ TEST(StorageV2, EdgePropertyAbort) {
ASSERT_EQ(edge.EdgeType(), et);
ASSERT_EQ(edge.FromVertex(), vertex);
ASSERT_EQ(edge.ToVertex(), vertex);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Set property 5 to "nandare", but abort the transaction.
@ -4382,7 +4382,7 @@ TEST(StorageV2, EdgePropertyAbort) {
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check that property 5 is "nandare".
@ -4538,7 +4538,7 @@ TEST(StorageV2, EdgePropertyAbort) {
ASSERT_TRUE(edge.GetProperty(property, storage::View::NEW)->IsNull());
ASSERT_EQ(edge.Properties(storage::View::NEW)->size(), 0);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Check that property 5 is null.
@ -4578,7 +4578,7 @@ TEST(StorageV2, EdgePropertySerializationError) {
ASSERT_EQ(edge.EdgeType(), et);
ASSERT_EQ(edge.FromVertex(), vertex);
ASSERT_EQ(edge.ToVertex(), vertex);
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
auto acc1 = store.Access();
@ -4642,7 +4642,7 @@ TEST(StorageV2, EdgePropertySerializationError) {
}
// Finalize both accessors.
acc1.Commit();
ASSERT_EQ(acc1.Commit(), std::nullopt);
acc2.Abort();
// Check which properties exist.

View File

@ -47,7 +47,7 @@ TEST(StorageV2Gc, Sanity) {
EXPECT_EQ(vertex_new.has_value(), i % 5 != 0);
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Verify existing vertices and add labels to some of them.
@ -90,7 +90,7 @@ TEST(StorageV2Gc, Sanity) {
}
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
// Add and remove some edges.
@ -148,7 +148,7 @@ TEST(StorageV2Gc, Sanity) {
}
}
acc.Commit();
ASSERT_EQ(acc.Commit(), std::nullopt);
}
}
@ -171,7 +171,7 @@ TEST(StorageV2Gc, Indices) {
auto vertex = acc0.CreateVertex();
ASSERT_TRUE(*vertex.AddLabel(acc0.NameToLabel("label")));
}
acc0.Commit();
ASSERT_EQ(acc0.Commit(), std::nullopt);
}
{
auto acc1 = storage.Access();
@ -180,7 +180,7 @@ TEST(StorageV2Gc, Indices) {
for (auto vertex : acc2.Vertices(storage::View::OLD)) {
ASSERT_TRUE(*vertex.RemoveLabel(acc2.NameToLabel("label")));
}
acc2.Commit();
ASSERT_EQ(acc2.Commit(), std::nullopt);
// Wait for GC.
std::this_thread::sleep_for(std::chrono::milliseconds(300));