Files
memgraph/tests/unit/storage_v2_edge.cpp
2023-04-25 09:19:05 +00:00

5416 lines
232 KiB
C++

// Copyright 2023 Memgraph Ltd.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
// License, and you may not use this file except in compliance with the Business Source License.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <limits>
#include "storage/v2/edge_accessor.hpp"
#include "storage/v2/inmemory/storage.hpp"
using testing::UnorderedElementsAre;
class StorageEdgeTest : public ::testing::TestWithParam<bool> {};
INSTANTIATE_TEST_CASE_P(EdgesWithProperties, StorageEdgeTest, ::testing::Values(true));
INSTANTIATE_TEST_CASE_P(EdgesWithoutProperties, StorageEdgeTest, ::testing::Values(false));
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, EdgeCreateFromSmallerCommit) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_from = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
memgraph::storage::Gid gid_to = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create vertices
{
auto acc = store->Access();
auto vertex_from = acc->CreateVertex();
auto vertex_to = acc->CreateVertex();
gid_from = vertex_from->Gid();
gid_to = vertex_to->Gid();
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex_from, &*vertex_to, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex_from);
ASSERT_EQ(*edge->ToVertex(), *vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, EdgeCreateFromLargerCommit) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_from = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
memgraph::storage::Gid gid_to = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create vertices
{
auto acc = store->Access();
auto vertex_to = acc->CreateVertex();
auto vertex_from = acc->CreateVertex();
gid_to = vertex_to->Gid();
gid_from = vertex_from->Gid();
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex_from, &*vertex_to, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex_from);
ASSERT_EQ(*edge->ToVertex(), *vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, EdgeCreateFromSameCommit) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_vertex = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create vertex
{
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gid_vertex = vertex->Gid();
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex, &*vertex, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex);
ASSERT_EQ(*edge->ToVertex(), *vertex);
// Check edges without filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
{
auto ret = vertex->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, EdgeCreateFromSmallerAbort) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_from = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
memgraph::storage::Gid gid_to = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create vertices
{
auto acc = store->Access();
auto vertex_from = acc->CreateVertex();
auto vertex_to = acc->CreateVertex();
gid_from = vertex_from->Gid();
gid_to = vertex_to->Gid();
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge, but abort the transaction
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex_from, &*vertex_to, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex_from);
ASSERT_EQ(*edge->ToVertex(), *vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
acc->Abort();
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex_from, &*vertex_to, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex_from);
ASSERT_EQ(*edge->ToVertex(), *vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, EdgeCreateFromLargerAbort) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_from = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
memgraph::storage::Gid gid_to = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create vertices
{
auto acc = store->Access();
auto vertex_to = acc->CreateVertex();
auto vertex_from = acc->CreateVertex();
gid_to = vertex_to->Gid();
gid_from = vertex_from->Gid();
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge, but abort the transaction
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex_from, &*vertex_to, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex_from);
ASSERT_EQ(*edge->ToVertex(), *vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
acc->Abort();
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex_from, &*vertex_to, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex_from);
ASSERT_EQ(*edge->ToVertex(), *vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, EdgeCreateFromSameAbort) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_vertex = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create vertex
{
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gid_vertex = vertex->Gid();
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge, but abort the transaction
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex, &*vertex, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex);
ASSERT_EQ(*edge->ToVertex(), *vertex);
// Check edges without filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
acc->Abort();
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
// Check edges without filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex, &*vertex, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex);
ASSERT_EQ(*edge->ToVertex(), *vertex);
// Check edges without filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
{
auto ret = vertex->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, EdgeDeleteFromSmallerCommit) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_from = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
memgraph::storage::Gid gid_to = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create vertices
{
auto acc = store->Access();
auto vertex_from = acc->CreateVertex();
auto vertex_to = acc->CreateVertex();
gid_from = vertex_from->Gid();
gid_to = vertex_to->Gid();
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex_from, &*vertex_to, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex_from);
ASSERT_EQ(*edge->ToVertex(), *vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Delete edge
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto edge = std::move(vertex_from->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto res = acc->DeleteEdge(edge.get());
ASSERT_TRUE(res.HasValue());
ASSERT_TRUE(res.GetValue());
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, EdgeDeleteFromLargerCommit) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_from = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
memgraph::storage::Gid gid_to = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create vertices
{
auto acc = store->Access();
auto vertex_to = acc->CreateVertex();
auto vertex_from = acc->CreateVertex();
gid_from = vertex_from->Gid();
gid_to = vertex_to->Gid();
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex_from, &*vertex_to, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex_from);
ASSERT_EQ(*edge->ToVertex(), *vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Delete edge
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto edge = std::move(vertex_from->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto res = acc->DeleteEdge(edge.get());
ASSERT_TRUE(res.HasValue());
ASSERT_TRUE(res.GetValue());
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, EdgeDeleteFromSameCommit) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_vertex = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create vertex
{
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gid_vertex = vertex->Gid();
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex, &*vertex, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex);
ASSERT_EQ(*edge->ToVertex(), *vertex);
// Check edges without filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
{
auto ret = vertex->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Delete edge
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
auto et = acc->NameToEdgeType("et5");
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto res = acc->DeleteEdge(edge.get());
ASSERT_TRUE(res.HasValue());
ASSERT_TRUE(res.GetValue());
// Check edges without filters
{
auto ret = vertex->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
// Check edges without filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, EdgeDeleteFromSmallerAbort) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_from = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
memgraph::storage::Gid gid_to = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create vertices
{
auto acc = store->Access();
auto vertex_from = acc->CreateVertex();
auto vertex_to = acc->CreateVertex();
gid_from = vertex_from->Gid();
gid_to = vertex_to->Gid();
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex_from, &*vertex_to, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex_from);
ASSERT_EQ(*edge->ToVertex(), *vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Delete the edge, but abort the transaction
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto edge = std::move(vertex_from->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto res = acc->DeleteEdge(edge.get());
ASSERT_TRUE(res.HasValue());
ASSERT_TRUE(res.GetValue());
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
acc->Abort();
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Delete the edge
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto edge = std::move(vertex_from->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto res = acc->DeleteEdge(edge.get());
ASSERT_TRUE(res.HasValue());
ASSERT_TRUE(res.GetValue());
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, EdgeDeleteFromLargerAbort) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_from = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
memgraph::storage::Gid gid_to = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create vertices
{
auto acc = store->Access();
auto vertex_from = acc->CreateVertex();
auto vertex_to = acc->CreateVertex();
gid_from = vertex_from->Gid();
gid_to = vertex_to->Gid();
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge
{
auto acc = store->Access();
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex_from, &*vertex_to, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex_from);
ASSERT_EQ(*edge->ToVertex(), *vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Delete the edge, but abort the transaction
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto edge = std::move(vertex_from->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto res = acc->DeleteEdge(edge.get());
ASSERT_TRUE(res.HasValue());
ASSERT_TRUE(res.GetValue());
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
acc->Abort();
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Delete the edge
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
auto edge = std::move(vertex_from->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto res = acc->DeleteEdge(edge.get());
ASSERT_TRUE(res.HasValue());
ASSERT_TRUE(res.GetValue());
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 1);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_from)->size(), 1);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD, {}, &*vertex_to)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
// Check edges without filters
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, EdgeDeleteFromSameAbort) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_vertex = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create vertex
{
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gid_vertex = vertex->Gid();
ASSERT_FALSE(acc->Commit().HasError());
}
// Create edge
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(&*vertex, &*vertex, et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex);
ASSERT_EQ(*edge->ToVertex(), *vertex);
// Check edges without filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 0);
{
auto ret = vertex->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
{
auto ret = vertex->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Delete the edge, but abort the transaction
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
auto et = acc->NameToEdgeType("et5");
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto res = acc->DeleteEdge(edge.get());
ASSERT_TRUE(res.HasValue());
ASSERT_TRUE(res.GetValue());
// Check edges without filters
{
auto ret = vertex->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
acc->Abort();
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
auto et = acc->NameToEdgeType("et5");
// Check edges without filters
{
auto ret = vertex->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
{
auto ret = vertex->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW, {other_et}, &*vertex)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Delete the edge
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
auto et = acc->NameToEdgeType("et5");
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto res = acc->DeleteEdge(edge.get());
ASSERT_TRUE(res.HasValue());
ASSERT_TRUE(res.GetValue());
// Check edges without filters
{
auto ret = vertex->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex);
ASSERT_EQ(*e->ToVertex(), *vertex);
}
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 0);
auto other_et = acc->NameToEdgeType("other");
// Check edges with filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et})->size(), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {et, other_et})->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {}, &*vertex)->size(), 1);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD, {other_et}, &*vertex)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check whether the edge exists
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid_vertex, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex);
// Check edges without filters
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, VertexDetachDeleteSingleCommit) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_from = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
memgraph::storage::Gid gid_to = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create dataset
{
auto acc = store->Access();
auto vertex_from = acc->CreateVertex();
auto vertex_to = acc->CreateVertex();
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(vertex_from.get(), vertex_to.get(), et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex_from);
ASSERT_EQ(*edge->ToVertex(), *vertex_to);
gid_from = vertex_from->Gid();
gid_to = vertex_to->Gid();
// Check edges
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Detach delete vertex
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Delete must fail
{
auto ret = acc->DeleteVertex(&*vertex_from);
ASSERT_TRUE(ret.HasError());
ASSERT_EQ(ret.GetError(), memgraph::storage::Error::VERTEX_HAS_EDGES);
}
// Detach delete vertex
{
auto ret = acc->DetachDeleteVertex(&*vertex_from);
ASSERT_TRUE(ret.HasValue());
ASSERT_TRUE(*ret);
}
// Check edges
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
ASSERT_EQ(vertex_from->InDegree(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
ASSERT_EQ(vertex_from->OutDegree(memgraph::storage::View::NEW).GetError(),
memgraph::storage::Error::DELETED_OBJECT);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check dataset
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_FALSE(vertex_from);
ASSERT_TRUE(vertex_to);
// Check edges
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, VertexDetachDeleteMultipleCommit) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_vertex1 = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
memgraph::storage::Gid gid_vertex2 = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create dataset
{
auto acc = store->Access();
auto vertex1 = acc->CreateVertex();
auto vertex2 = acc->CreateVertex();
gid_vertex1 = vertex1->Gid();
gid_vertex2 = vertex2->Gid();
auto et1 = acc->NameToEdgeType("et1");
auto et2 = acc->NameToEdgeType("et2");
auto et3 = acc->NameToEdgeType("et3");
auto et4 = acc->NameToEdgeType("et4");
auto res1 = acc->CreateEdge(vertex1.get(), vertex2.get(), et1);
ASSERT_TRUE(res1.HasValue());
auto edge1 = std::move(res1.GetValue());
ASSERT_EQ(edge1->EdgeType(), et1);
ASSERT_EQ(*edge1->FromVertex(), *vertex1);
ASSERT_EQ(*edge1->ToVertex(), *vertex2);
auto res2 = acc->CreateEdge(vertex2.get(), vertex1.get(), et2);
ASSERT_TRUE(res2.HasValue());
auto edge2 = std::move(res2.GetValue());
ASSERT_EQ(edge2->EdgeType(), et2);
ASSERT_EQ(*edge2->FromVertex(), *vertex2);
ASSERT_EQ(*edge2->ToVertex(), *vertex1);
auto res3 = acc->CreateEdge(vertex1.get(), vertex1.get(), et3);
ASSERT_TRUE(res3.HasValue());
auto edge3 = std::move(res3.GetValue());
ASSERT_EQ(edge3->EdgeType(), et3);
ASSERT_EQ(*edge3->FromVertex(), *vertex1);
ASSERT_EQ(*edge3->ToVertex(), *vertex1);
auto res4 = acc->CreateEdge(vertex2.get(), vertex2.get(), et4);
ASSERT_TRUE(res4.HasValue());
auto edge4 = std::move(res4.GetValue());
ASSERT_EQ(edge4->EdgeType(), et4);
ASSERT_EQ(*edge4->FromVertex(), *vertex2);
ASSERT_EQ(*edge4->ToVertex(), *vertex2);
// Check edges
{
auto ret = vertex1->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->InDegree(memgraph::storage::View::NEW), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
{
auto ret = vertex1->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->OutDegree(memgraph::storage::View::NEW), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
{
auto ret = vertex2->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::NEW), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::NEW), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
ASSERT_FALSE(acc->Commit().HasError());
}
// Detach delete vertex
{
auto acc = store->Access();
auto vertex1 = acc->FindVertex(gid_vertex1, memgraph::storage::View::NEW);
auto vertex2 = acc->FindVertex(gid_vertex2, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex1);
ASSERT_TRUE(vertex2);
auto et1 = acc->NameToEdgeType("et1");
auto et2 = acc->NameToEdgeType("et2");
auto et3 = acc->NameToEdgeType("et3");
auto et4 = acc->NameToEdgeType("et4");
// Delete must fail
{
auto ret = acc->DeleteVertex(&*vertex1);
ASSERT_TRUE(ret.HasError());
ASSERT_EQ(ret.GetError(), memgraph::storage::Error::VERTEX_HAS_EDGES);
}
// Detach delete vertex
{
auto ret = acc->DetachDeleteVertex(&*vertex1);
ASSERT_TRUE(ret.HasValue());
ASSERT_TRUE(*ret);
}
// Check edges
{
auto ret = vertex1->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->InDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
ASSERT_EQ(vertex1->InEdges(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
ASSERT_EQ(vertex1->InDegree(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
{
auto ret = vertex1->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->OutDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
ASSERT_EQ(vertex1->OutEdges(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
ASSERT_EQ(vertex1->OutDegree(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
{
auto ret = vertex2->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
{
auto ret = vertex2->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
ASSERT_FALSE(acc->Commit().HasError());
}
// Check dataset
{
auto acc = store->Access();
auto vertex1 = acc->FindVertex(gid_vertex1, memgraph::storage::View::NEW);
auto vertex2 = acc->FindVertex(gid_vertex2, memgraph::storage::View::NEW);
ASSERT_FALSE(vertex1);
ASSERT_TRUE(vertex2);
auto et4 = acc->NameToEdgeType("et4");
// Check edges
{
auto ret = vertex2->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto ret = vertex2->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, VertexDetachDeleteSingleAbort) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_from = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
memgraph::storage::Gid gid_to = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create dataset
{
auto acc = store->Access();
auto vertex_from = acc->CreateVertex();
auto vertex_to = acc->CreateVertex();
auto et = acc->NameToEdgeType("et5");
auto res = acc->CreateEdge(vertex_from.get(), vertex_to.get(), et);
ASSERT_TRUE(res.HasValue());
auto edge = std::move(res.GetValue());
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex_from);
ASSERT_EQ(*edge->ToVertex(), *vertex_to);
gid_from = vertex_from->Gid();
gid_to = vertex_to->Gid();
// Check edges
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Detach delete vertex, but abort the transaction
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Delete must fail
{
auto ret = acc->DeleteVertex(&*vertex_from);
ASSERT_TRUE(ret.HasError());
ASSERT_EQ(ret.GetError(), memgraph::storage::Error::VERTEX_HAS_EDGES);
}
// Detach delete vertex
{
auto ret = acc->DetachDeleteVertex(&*vertex_from);
ASSERT_TRUE(ret.HasValue());
ASSERT_TRUE(*ret);
}
// Check edges
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
ASSERT_EQ(vertex_from->InDegree(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
ASSERT_EQ(vertex_from->OutDegree(memgraph::storage::View::NEW).GetError(),
memgraph::storage::Error::DELETED_OBJECT);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
acc->Abort();
}
// Check dataset
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Check edges
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::NEW), 0);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
{
auto ret = vertex_to->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Detach delete vertex
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex_from);
ASSERT_TRUE(vertex_to);
auto et = acc->NameToEdgeType("et5");
// Delete must fail
{
auto ret = acc->DeleteVertex(&*vertex_from);
ASSERT_TRUE(ret.HasError());
ASSERT_EQ(ret.GetError(), memgraph::storage::Error::VERTEX_HAS_EDGES);
}
// Detach delete vertex
{
auto ret = acc->DetachDeleteVertex(&*vertex_from);
ASSERT_TRUE(ret.HasValue());
ASSERT_TRUE(*ret);
}
// Check edges
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_from->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_from->InEdges(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
ASSERT_EQ(vertex_from->InDegree(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
{
auto ret = vertex_from->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_from->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_from->OutEdges(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
ASSERT_EQ(vertex_from->OutDegree(memgraph::storage::View::NEW).GetError(),
memgraph::storage::Error::DELETED_OBJECT);
{
auto ret = vertex_to->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et);
ASSERT_EQ(*e->FromVertex(), *vertex_from);
ASSERT_EQ(*e->ToVertex(), *vertex_to);
}
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check dataset
{
auto acc = store->Access();
auto vertex_from = acc->FindVertex(gid_from, memgraph::storage::View::NEW);
auto vertex_to = acc->FindVertex(gid_to, memgraph::storage::View::NEW);
ASSERT_FALSE(vertex_from);
ASSERT_TRUE(vertex_to);
// Check edges
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->InEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->InDegree(memgraph::storage::View::NEW), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::OLD), 0);
ASSERT_EQ(vertex_to->OutEdges(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*vertex_to->OutDegree(memgraph::storage::View::NEW), 0);
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST_P(StorageEdgeTest, VertexDetachDeleteMultipleAbort) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = GetParam()}}));
memgraph::storage::Gid gid_vertex1 = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
memgraph::storage::Gid gid_vertex2 = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create dataset
{
auto acc = store->Access();
auto vertex1 = acc->CreateVertex();
auto vertex2 = acc->CreateVertex();
gid_vertex1 = vertex1->Gid();
gid_vertex2 = vertex2->Gid();
auto et1 = acc->NameToEdgeType("et1");
auto et2 = acc->NameToEdgeType("et2");
auto et3 = acc->NameToEdgeType("et3");
auto et4 = acc->NameToEdgeType("et4");
auto res1 = acc->CreateEdge(vertex1.get(), vertex2.get(), et1);
ASSERT_TRUE(res1.HasValue());
auto edge1 = std::move(res1.GetValue());
ASSERT_EQ(edge1->EdgeType(), et1);
ASSERT_EQ(*edge1->FromVertex(), *vertex1);
ASSERT_EQ(*edge1->ToVertex(), *vertex2);
auto res2 = acc->CreateEdge(vertex2.get(), vertex1.get(), et2);
ASSERT_TRUE(res2.HasValue());
auto edge2 = std::move(res2.GetValue());
ASSERT_EQ(edge2->EdgeType(), et2);
ASSERT_EQ(*edge2->FromVertex(), *vertex2);
ASSERT_EQ(*edge2->ToVertex(), *vertex1);
auto res3 = acc->CreateEdge(vertex1.get(), vertex1.get(), et3);
ASSERT_TRUE(res3.HasValue());
auto edge3 = std::move(res3.GetValue());
ASSERT_EQ(edge3->EdgeType(), et3);
ASSERT_EQ(*edge3->FromVertex(), *vertex1);
ASSERT_EQ(*edge3->ToVertex(), *vertex1);
auto res4 = acc->CreateEdge(vertex2.get(), vertex2.get(), et4);
ASSERT_TRUE(res4.HasValue());
auto edge4 = std::move(res4.GetValue());
ASSERT_EQ(edge4->EdgeType(), et4);
ASSERT_EQ(*edge4->FromVertex(), *vertex2);
ASSERT_EQ(*edge4->ToVertex(), *vertex2);
// Check edges
{
auto ret = vertex1->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->InDegree(memgraph::storage::View::NEW), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
{
auto ret = vertex1->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->OutDegree(memgraph::storage::View::NEW), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
{
auto ret = vertex2->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::NEW), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::NEW), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
ASSERT_FALSE(acc->Commit().HasError());
}
// Detach delete vertex, but abort the transaction
{
auto acc = store->Access();
auto vertex1 = acc->FindVertex(gid_vertex1, memgraph::storage::View::NEW);
auto vertex2 = acc->FindVertex(gid_vertex2, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex1);
ASSERT_TRUE(vertex2);
auto et1 = acc->NameToEdgeType("et1");
auto et2 = acc->NameToEdgeType("et2");
auto et3 = acc->NameToEdgeType("et3");
auto et4 = acc->NameToEdgeType("et4");
// Delete must fail
{
auto ret = acc->DeleteVertex(&*vertex1);
ASSERT_TRUE(ret.HasError());
ASSERT_EQ(ret.GetError(), memgraph::storage::Error::VERTEX_HAS_EDGES);
}
// Detach delete vertex
{
auto ret = acc->DetachDeleteVertex(&*vertex1);
ASSERT_TRUE(ret.HasValue());
ASSERT_TRUE(*ret);
}
// Check edges
{
auto ret = vertex1->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->InDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
ASSERT_EQ(vertex1->InEdges(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
ASSERT_EQ(vertex1->InDegree(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
{
auto ret = vertex1->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->OutDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
ASSERT_EQ(vertex1->OutEdges(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
ASSERT_EQ(vertex1->OutDegree(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
{
auto ret = vertex2->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
{
auto ret = vertex2->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
acc->Abort();
}
// Check dataset
{
auto acc = store->Access();
auto vertex1 = acc->FindVertex(gid_vertex1, memgraph::storage::View::NEW);
auto vertex2 = acc->FindVertex(gid_vertex2, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex1);
ASSERT_TRUE(vertex2);
auto et1 = acc->NameToEdgeType("et1");
auto et2 = acc->NameToEdgeType("et2");
auto et3 = acc->NameToEdgeType("et3");
auto et4 = acc->NameToEdgeType("et4");
// Check edges
{
auto ret = vertex1->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->InDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
{
auto ret = vertex1->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->InDegree(memgraph::storage::View::NEW), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
{
auto ret = vertex1->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->OutDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
{
auto ret = vertex1->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->OutDegree(memgraph::storage::View::NEW), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
{
auto ret = vertex2->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
{
auto ret = vertex2->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::NEW), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::NEW), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
ASSERT_FALSE(acc->Commit().HasError());
}
// Detach delete vertex
{
auto acc = store->Access();
auto vertex1 = acc->FindVertex(gid_vertex1, memgraph::storage::View::NEW);
auto vertex2 = acc->FindVertex(gid_vertex2, memgraph::storage::View::NEW);
ASSERT_TRUE(vertex1);
ASSERT_TRUE(vertex2);
auto et1 = acc->NameToEdgeType("et1");
auto et2 = acc->NameToEdgeType("et2");
auto et3 = acc->NameToEdgeType("et3");
auto et4 = acc->NameToEdgeType("et4");
// Delete must fail
{
auto ret = acc->DeleteVertex(&*vertex1);
ASSERT_TRUE(ret.HasError());
ASSERT_EQ(ret.GetError(), memgraph::storage::Error::VERTEX_HAS_EDGES);
}
// Detach delete vertex
{
auto ret = acc->DetachDeleteVertex(&*vertex1);
ASSERT_TRUE(ret.HasValue());
ASSERT_TRUE(*ret);
}
// Check edges
{
auto ret = vertex1->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->InDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
ASSERT_EQ(vertex1->InEdges(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
ASSERT_EQ(vertex1->InDegree(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
{
auto ret = vertex1->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex1->OutDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et3);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
}
ASSERT_EQ(vertex1->OutEdges(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
ASSERT_EQ(vertex1->OutDegree(memgraph::storage::View::NEW).GetError(), memgraph::storage::Error::DELETED_OBJECT);
{
auto ret = vertex2->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et1);
ASSERT_EQ(*e->FromVertex(), *vertex1);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
{
auto ret = vertex2->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
std::sort(edges.begin(), edges.end(), [](const auto &a, const auto &b) { return a->EdgeType() < b->EdgeType(); });
ASSERT_EQ(edges.size(), 2);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::OLD), 2);
{
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et2);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex1);
}
{
auto e = std::move(edges[1]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
ASSERT_FALSE(acc->Commit().HasError());
}
// Check dataset
{
auto acc = store->Access();
auto vertex1 = acc->FindVertex(gid_vertex1, memgraph::storage::View::NEW);
auto vertex2 = acc->FindVertex(gid_vertex2, memgraph::storage::View::NEW);
ASSERT_FALSE(vertex1);
ASSERT_TRUE(vertex2);
auto et4 = acc->NameToEdgeType("et4");
// Check edges
{
auto ret = vertex2->InEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto ret = vertex2->InEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->InDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::OLD);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::OLD), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
{
auto ret = vertex2->OutEdges(memgraph::storage::View::NEW);
ASSERT_TRUE(ret.HasValue());
auto edges = std::move(ret.GetValue());
ASSERT_EQ(edges.size(), 1);
ASSERT_EQ(*vertex2->OutDegree(memgraph::storage::View::NEW), 1);
auto e = std::move(edges[0]);
ASSERT_EQ(e->EdgeType(), et4);
ASSERT_EQ(*e->FromVertex(), *vertex2);
ASSERT_EQ(*e->ToVertex(), *vertex2);
}
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST(StorageWithProperties, EdgePropertyCommit) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = true}}));
memgraph::storage::Gid gid = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
{
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gid = vertex->Gid();
auto et = acc->NameToEdgeType("et5");
auto edge = acc->CreateEdge(vertex.get(), vertex.get(), et).GetValue();
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex);
ASSERT_EQ(*edge->ToVertex(), *vertex);
auto property = acc->NameToProperty("property5");
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
{
auto old_value = edge->SetProperty(property, memgraph::storage::PropertyValue("temporary"));
ASSERT_TRUE(old_value.HasValue());
ASSERT_TRUE(old_value->IsNull());
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::NEW)->ValueString(), "temporary");
{
auto properties = edge->Properties(memgraph::storage::View::NEW).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "temporary");
}
{
auto old_value = edge->SetProperty(property, memgraph::storage::PropertyValue("nandare"));
ASSERT_TRUE(old_value.HasValue());
ASSERT_FALSE(old_value->IsNull());
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::NEW)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::NEW).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
ASSERT_FALSE(acc->Commit().HasError());
}
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property = acc->NameToProperty("property5");
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::OLD)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::OLD).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::NEW)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::NEW).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
auto other_property = acc->NameToProperty("other");
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::NEW)->IsNull());
acc->Abort();
}
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property = acc->NameToProperty("property5");
{
auto old_value = edge->SetProperty(property, memgraph::storage::PropertyValue());
ASSERT_TRUE(old_value.HasValue());
ASSERT_FALSE(old_value->IsNull());
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::OLD)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::OLD).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
{
auto old_value = edge->SetProperty(property, memgraph::storage::PropertyValue());
ASSERT_TRUE(old_value.HasValue());
ASSERT_TRUE(old_value->IsNull());
}
ASSERT_FALSE(acc->Commit().HasError());
}
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property = acc->NameToProperty("property5");
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
auto other_property = acc->NameToProperty("other");
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::NEW)->IsNull());
acc->Abort();
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST(StorageWithProperties, EdgePropertyAbort) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = true}}));
memgraph::storage::Gid gid = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
// Create the vertex.
{
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gid = vertex->Gid();
auto et = acc->NameToEdgeType("et5");
auto edge = acc->CreateEdge(vertex.get(), vertex.get(), et).GetValue();
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex);
ASSERT_EQ(*edge->ToVertex(), *vertex);
ASSERT_FALSE(acc->Commit().HasError());
}
// Set property 5 to "nandare", but abort the transaction.
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property = acc->NameToProperty("property5");
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
{
auto old_value = edge->SetProperty(property, memgraph::storage::PropertyValue("temporary"));
ASSERT_TRUE(old_value.HasValue());
ASSERT_TRUE(old_value->IsNull());
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::NEW)->ValueString(), "temporary");
{
auto properties = edge->Properties(memgraph::storage::View::NEW).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "temporary");
}
{
auto old_value = edge->SetProperty(property, memgraph::storage::PropertyValue("nandare"));
ASSERT_TRUE(old_value.HasValue());
ASSERT_FALSE(old_value->IsNull());
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::NEW)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::NEW).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
acc->Abort();
}
// Check that property 5 is null.
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property = acc->NameToProperty("property5");
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
auto other_property = acc->NameToProperty("other");
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::NEW)->IsNull());
acc->Abort();
}
// Set property 5 to "nandare".
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property = acc->NameToProperty("property5");
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
{
auto old_value = edge->SetProperty(property, memgraph::storage::PropertyValue("temporary"));
ASSERT_TRUE(old_value.HasValue());
ASSERT_TRUE(old_value->IsNull());
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::NEW)->ValueString(), "temporary");
{
auto properties = edge->Properties(memgraph::storage::View::NEW).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "temporary");
}
{
auto old_value = edge->SetProperty(property, memgraph::storage::PropertyValue("nandare"));
ASSERT_TRUE(old_value.HasValue());
ASSERT_FALSE(old_value->IsNull());
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::NEW)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::NEW).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
ASSERT_FALSE(acc->Commit().HasError());
}
// Check that property 5 is "nandare".
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property = acc->NameToProperty("property5");
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::OLD)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::OLD).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::NEW)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::NEW).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
auto other_property = acc->NameToProperty("other");
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::NEW)->IsNull());
acc->Abort();
}
// Set property 5 to null, but abort the transaction.
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property = acc->NameToProperty("property5");
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::OLD)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::OLD).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::NEW)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::NEW).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
{
auto old_value = edge->SetProperty(property, memgraph::storage::PropertyValue());
ASSERT_TRUE(old_value.HasValue());
ASSERT_FALSE(old_value->IsNull());
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::OLD)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::OLD).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
acc->Abort();
}
// Check that property 5 is "nandare".
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property = acc->NameToProperty("property5");
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::OLD)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::OLD).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::NEW)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::NEW).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
auto other_property = acc->NameToProperty("other");
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::NEW)->IsNull());
acc->Abort();
}
// Set property 5 to null.
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property = acc->NameToProperty("property5");
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::OLD)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::OLD).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::NEW)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::NEW).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
{
auto old_value = edge->SetProperty(property, memgraph::storage::PropertyValue());
ASSERT_TRUE(old_value.HasValue());
ASSERT_FALSE(old_value->IsNull());
}
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::OLD)->ValueString(), "nandare");
{
auto properties = edge->Properties(memgraph::storage::View::OLD).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property].ValueString(), "nandare");
}
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
// Check that property 5 is null.
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property = acc->NameToProperty("property5");
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
auto other_property = acc->NameToProperty("other");
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::NEW)->IsNull());
acc->Abort();
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST(StorageWithProperties, EdgePropertySerializationError) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = true}}));
memgraph::storage::Gid gid = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
{
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gid = vertex->Gid();
auto et = acc->NameToEdgeType("et5");
auto edge = acc->CreateEdge(vertex.get(), vertex.get(), et).GetValue();
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex);
ASSERT_EQ(*edge->ToVertex(), *vertex);
ASSERT_FALSE(acc->Commit().HasError());
}
auto acc1 = store->Access();
auto acc2 = store->Access();
// Set property 1 to 123 in accessor 1.
{
auto vertex = acc1->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property1 = acc1->NameToProperty("property1");
auto property2 = acc1->NameToProperty("property2");
ASSERT_TRUE(edge->GetProperty(property1, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(property1, memgraph::storage::View::NEW)->IsNull());
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
{
auto old_value = edge->SetProperty(property1, memgraph::storage::PropertyValue(123));
ASSERT_TRUE(old_value.HasValue());
ASSERT_TRUE(old_value->IsNull());
}
ASSERT_TRUE(edge->GetProperty(property1, memgraph::storage::View::OLD)->IsNull());
ASSERT_EQ(edge->GetProperty(property1, memgraph::storage::View::NEW)->ValueInt(), 123);
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::OLD)->size(), 0);
{
auto properties = edge->Properties(memgraph::storage::View::NEW).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property1].ValueInt(), 123);
}
}
// Set property 2 to "nandare" in accessor 2.
{
auto vertex = acc2->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property1 = acc2->NameToProperty("property1");
auto property2 = acc2->NameToProperty("property2");
ASSERT_TRUE(edge->GetProperty(property1, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(property1, memgraph::storage::View::NEW)->IsNull());
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::OLD)->size(), 0);
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
{
auto res = edge->SetProperty(property2, memgraph::storage::PropertyValue("nandare"));
ASSERT_TRUE(res.HasError());
ASSERT_EQ(res.GetError(), memgraph::storage::Error::SERIALIZATION_ERROR);
}
}
// Finalize both accessors.
ASSERT_FALSE(acc1->Commit().HasError());
acc2->Abort();
// Check which properties exist.
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property1 = acc->NameToProperty("property1");
auto property2 = acc->NameToProperty("property2");
ASSERT_EQ(edge->GetProperty(property1, memgraph::storage::View::OLD)->ValueInt(), 123);
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::OLD)->IsNull());
{
auto properties = edge->Properties(memgraph::storage::View::OLD).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property1].ValueInt(), 123);
}
ASSERT_EQ(edge->GetProperty(property1, memgraph::storage::View::NEW)->ValueInt(), 123);
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::NEW)->IsNull());
{
auto properties = edge->Properties(memgraph::storage::View::NEW).GetValue();
ASSERT_EQ(properties.size(), 1);
ASSERT_EQ(properties[property1].ValueInt(), 123);
}
acc->Abort();
}
}
TEST(StorageWithProperties, EdgePropertyClear) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = true}}));
memgraph::storage::Gid gid;
auto property1 = store->NameToProperty("property1");
auto property2 = store->NameToProperty("property2");
{
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gid = vertex->Gid();
auto et = acc->NameToEdgeType("et5");
auto edge = acc->CreateEdge(vertex.get(), vertex.get(), et).GetValue();
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex);
ASSERT_EQ(*edge->ToVertex(), *vertex);
auto old_value = edge->SetProperty(property1, memgraph::storage::PropertyValue("value"));
ASSERT_TRUE(old_value.HasValue());
ASSERT_TRUE(old_value->IsNull());
ASSERT_FALSE(acc->Commit().HasError());
}
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
ASSERT_EQ(edge->GetProperty(property1, memgraph::storage::View::OLD)->ValueString(), "value");
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::OLD)->IsNull());
ASSERT_THAT(edge->Properties(memgraph::storage::View::OLD).GetValue(),
UnorderedElementsAre(std::pair(property1, memgraph::storage::PropertyValue("value"))));
{
auto old_values = edge->ClearProperties();
ASSERT_TRUE(old_values.HasValue());
ASSERT_FALSE(old_values->empty());
}
ASSERT_TRUE(edge->GetProperty(property1, memgraph::storage::View::NEW)->IsNull());
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW).GetValue().size(), 0);
{
auto old_values = edge->ClearProperties();
ASSERT_TRUE(old_values.HasValue());
ASSERT_TRUE(old_values->empty());
}
ASSERT_TRUE(edge->GetProperty(property1, memgraph::storage::View::NEW)->IsNull());
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW).GetValue().size(), 0);
acc->Abort();
}
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto old_value = edge->SetProperty(property2, memgraph::storage::PropertyValue(42));
ASSERT_TRUE(old_value.HasValue());
ASSERT_TRUE(old_value->IsNull());
ASSERT_FALSE(acc->Commit().HasError());
}
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
ASSERT_EQ(edge->GetProperty(property1, memgraph::storage::View::OLD)->ValueString(), "value");
ASSERT_EQ(edge->GetProperty(property2, memgraph::storage::View::OLD)->ValueInt(), 42);
ASSERT_THAT(edge->Properties(memgraph::storage::View::OLD).GetValue(),
UnorderedElementsAre(std::pair(property1, memgraph::storage::PropertyValue("value")),
std::pair(property2, memgraph::storage::PropertyValue(42))));
{
auto old_values = edge->ClearProperties();
ASSERT_TRUE(old_values.HasValue());
ASSERT_FALSE(old_values->empty());
}
ASSERT_TRUE(edge->GetProperty(property1, memgraph::storage::View::NEW)->IsNull());
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW).GetValue().size(), 0);
{
auto old_values = edge->ClearProperties();
ASSERT_TRUE(old_values.HasValue());
ASSERT_TRUE(old_values->empty());
}
ASSERT_TRUE(edge->GetProperty(property1, memgraph::storage::View::NEW)->IsNull());
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW).GetValue().size(), 0);
ASSERT_FALSE(acc->Commit().HasError());
}
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
ASSERT_TRUE(edge->GetProperty(property1, memgraph::storage::View::NEW)->IsNull());
ASSERT_TRUE(edge->GetProperty(property2, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW).GetValue().size(), 0);
acc->Abort();
}
}
// NOLINTNEXTLINE(hicpp-special-member-functions)
TEST(StorageWithoutProperties, EdgePropertyAbort) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = false}}));
memgraph::storage::Gid gid = memgraph::storage::Gid::FromUint(std::numeric_limits<uint64_t>::max());
{
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gid = vertex->Gid();
auto et = acc->NameToEdgeType("et5");
auto edge = acc->CreateEdge(vertex.get(), vertex.get(), et).GetValue();
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex);
ASSERT_EQ(*edge->ToVertex(), *vertex);
ASSERT_FALSE(acc->Commit().HasError());
}
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property = acc->NameToProperty("property5");
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
{
auto res = edge->SetProperty(property, memgraph::storage::PropertyValue("temporary"));
ASSERT_TRUE(res.HasError());
ASSERT_EQ(res.GetError(), memgraph::storage::Error::PROPERTIES_DISABLED);
}
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
{
auto res = edge->SetProperty(property, memgraph::storage::PropertyValue("nandare"));
ASSERT_TRUE(res.HasError());
ASSERT_EQ(res.GetError(), memgraph::storage::Error::PROPERTIES_DISABLED);
}
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
acc->Abort();
}
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
auto property = acc->NameToProperty("property5");
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::OLD)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::OLD)->size(), 0);
ASSERT_TRUE(edge->GetProperty(property, memgraph::storage::View::NEW)->IsNull());
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
auto other_property = acc->NameToProperty("other");
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::OLD)->IsNull());
ASSERT_TRUE(edge->GetProperty(other_property, memgraph::storage::View::NEW)->IsNull());
acc->Abort();
}
}
TEST(StorageWithoutProperties, EdgePropertyClear) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = false}}));
memgraph::storage::Gid gid;
{
auto acc = store->Access();
auto vertex = acc->CreateVertex();
gid = vertex->Gid();
auto et = acc->NameToEdgeType("et5");
auto edge = acc->CreateEdge(vertex.get(), vertex.get(), et).GetValue();
ASSERT_EQ(edge->EdgeType(), et);
ASSERT_EQ(*edge->FromVertex(), *vertex);
ASSERT_EQ(*edge->ToVertex(), *vertex);
ASSERT_FALSE(acc->Commit().HasError());
}
{
auto acc = store->Access();
auto vertex = acc->FindVertex(gid, memgraph::storage::View::OLD);
ASSERT_TRUE(vertex);
auto edge = std::move(vertex->OutEdges(memgraph::storage::View::NEW).GetValue()[0]);
ASSERT_EQ(edge->ClearProperties().GetError(), memgraph::storage::Error::PROPERTIES_DISABLED);
acc->Abort();
}
}
TEST(StorageWithProperties, EdgeNonexistentPropertyAPI) {
std::unique_ptr<memgraph::storage::Storage> store(
new memgraph::storage::InMemoryStorage({.items = {.properties_on_edges = true}}));
auto property = store->NameToProperty("property");
auto acc = store->Access();
auto vertex = acc->CreateVertex();
auto edgeRes = acc->CreateEdge(vertex.get(), vertex.get(), acc->NameToEdgeType("edge"));
ASSERT_TRUE(edgeRes.HasValue());
auto edge = std::move(edgeRes.GetValue());
// Check state before (OLD view).
ASSERT_EQ(edge->Properties(memgraph::storage::View::OLD).GetError(), memgraph::storage::Error::NONEXISTENT_OBJECT);
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::OLD).GetError(),
memgraph::storage::Error::NONEXISTENT_OBJECT);
// Check state before (NEW view).
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 0);
ASSERT_EQ(*edge->GetProperty(property, memgraph::storage::View::NEW), memgraph::storage::PropertyValue());
// Modify edge.
ASSERT_TRUE(edge->SetProperty(property, memgraph::storage::PropertyValue("value"))->IsNull());
// Check state after (OLD view).
ASSERT_EQ(edge->Properties(memgraph::storage::View::OLD).GetError(), memgraph::storage::Error::NONEXISTENT_OBJECT);
ASSERT_EQ(edge->GetProperty(property, memgraph::storage::View::OLD).GetError(),
memgraph::storage::Error::NONEXISTENT_OBJECT);
// Check state after (NEW view).
ASSERT_EQ(edge->Properties(memgraph::storage::View::NEW)->size(), 1);
ASSERT_EQ(*edge->GetProperty(property, memgraph::storage::View::NEW), memgraph::storage::PropertyValue("value"));
ASSERT_FALSE(acc->Commit().HasError());
}