Removed storage changes

This commit is contained in:
niko4299
2022-08-01 11:23:43 +02:00
parent c830bc7d81
commit 3843366e7b
8 changed files with 66 additions and 143 deletions

View File

@@ -1,26 +0,0 @@
// Copyright 2022 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.
#pragma once
#include "auth/models.hpp"
#include "query/frontend/ast/ast.hpp"
#include "storage/v2/id_types.hpp"
namespace memgraph::query {
class AccessChecker {
public:
virtual bool IsUserAuthorizedEdgeTypes(const std::vector<memgraph::storage::EdgeTypeId> &edgeTypes,
memgraph::query::DbAccessor *dba) const = 0;
virtual std::vector<memgraph::storage::EdgeTypeId> GetGrantedEdgeTypesId(memgraph::query::DbAccessor *dba) const = 0;
};
} // namespace memgraph::query

View File

@@ -17,7 +17,6 @@
#include <cppitertools/imap.hpp>
#include "query/exceptions.hpp"
#include "query/fine_grained_access_checker.hpp"
#include "storage/v2/id_types.hpp"
#include "storage/v2/property_value.hpp"
#include "storage/v2/result.hpp"
@@ -131,48 +130,35 @@ class VertexAccessor final {
return impl_.ClearProperties();
}
auto InEdges(storage::View view, const std::vector<storage::EdgeTypeId> &edge_types,
const FineGrainedAccessChecker *fine_grained_access_checker) const
auto InEdges(storage::View view, const std::vector<storage::EdgeTypeId> &edge_types) const
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor, *impl_.InEdges(view)))> {
auto maybe_edges = impl_.InEdges(view, edge_types, fine_grained_access_checker);
auto maybe_edges = impl_.InEdges(view, edge_types);
if (maybe_edges.HasError()) return maybe_edges.GetError();
return iter::imap(MakeEdgeAccessor, std::move(*maybe_edges));
}
auto InEdges(storage::View view) const
auto InEdges(storage::View view) const { return InEdges(view, {}); }
auto InEdges(storage::View view, const std::vector<storage::EdgeTypeId> &edge_types, const VertexAccessor &dest) const
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor, *impl_.InEdges(view)))> {
auto maybe_edges = impl_.InEdges(view, {}, nullptr);
auto maybe_edges = impl_.InEdges(view, edge_types, &dest.impl_);
if (maybe_edges.HasError()) return maybe_edges.GetError();
return iter::imap(MakeEdgeAccessor, std::move(*maybe_edges));
}
auto InEdges(storage::View view, const std::vector<storage::EdgeTypeId> &edge_types,
const FineGrainedAccessChecker *fine_grained_access_checker, const VertexAccessor &dest) const
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor, *impl_.InEdges(view)))> {
auto maybe_edges = impl_.InEdges(view, edge_types, fine_grained_access_checker, &dest.impl_);
auto OutEdges(storage::View view, const std::vector<storage::EdgeTypeId> &edge_types) const
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor, *impl_.OutEdges(view)))> {
auto maybe_edges = impl_.OutEdges(view, edge_types);
if (maybe_edges.HasError()) return maybe_edges.GetError();
return iter::imap(MakeEdgeAccessor, std::move(*maybe_edges));
}
auto OutEdges(storage::View view) const { return OutEdges(view, {}); }
auto OutEdges(storage::View view, const std::vector<storage::EdgeTypeId> &edge_types,
const FineGrainedAccessChecker *fine_grained_access_checker) const
const VertexAccessor &dest) const
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor, *impl_.OutEdges(view)))> {
auto maybe_edges = impl_.OutEdges(view, edge_types, fine_grained_access_checker);
if (maybe_edges.HasError()) return maybe_edges.GetError();
return iter::imap(MakeEdgeAccessor, std::move(*maybe_edges));
}
auto OutEdges(storage::View view) const
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor, *impl_.OutEdges(view)))> {
auto maybe_edges = impl_.OutEdges(view, {}, nullptr);
if (maybe_edges.HasError()) return maybe_edges.GetError();
return iter::imap(MakeEdgeAccessor, std::move(*maybe_edges));
}
auto OutEdges(storage::View view, const std::vector<storage::EdgeTypeId> &edge_types,
const FineGrainedAccessChecker *fine_grained_access_checker, const VertexAccessor &dest) const
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor, *impl_.OutEdges(view)))> {
auto maybe_edges = impl_.OutEdges(view, edge_types, fine_grained_access_checker, &dest.impl_);
auto maybe_edges = impl_.OutEdges(view, edge_types, &dest.impl_);
if (maybe_edges.HasError()) return maybe_edges.GetError();
return iter::imap(MakeEdgeAccessor, std::move(*maybe_edges));
}
@@ -375,6 +361,7 @@ class DbAccessor final {
} // namespace memgraph::query
namespace std {
template <>
struct hash<memgraph::query::VertexAccessor> {
size_t operator()(const memgraph::query::VertexAccessor &v) const { return std::hash<decltype(v.impl_)>{}(v.impl_); }

View File

@@ -11,11 +11,17 @@
#pragma once
#include "query/db_accessor.hpp"
#include "storage/v2/id_types.hpp"
namespace memgraph::query {
class FineGrainedAccessChecker {
public:
virtual bool Accept(VertexAccessor &vertex) = 0;
virtual bool Accept(EdgeAccessor &edge) = 0;
private:
virtual bool IsUserAuthorizedLabels(const std::vector<memgraph::storage::LabelId> &labels) const = 0;
virtual bool IsUserAuthorizedEdgeType(const memgraph::storage::EdgeTypeId &edgeType) const = 0;

View File

@@ -266,6 +266,13 @@ class FineGrainedAccessChecker final : public memgraph::query::FineGrainedAccess
public:
explicit FineGrainedAccessChecker(memgraph::auth::User *user, DbAccessor *dba) : user_{user}, dba_{dba} {}
bool Accept(VertexAccessor &vertex) {
return IsUserAuthorizedLabels(vertex.Labels(memgraph::storage::View::NEW).GetValue());
}
bool Accept(EdgeAccessor &edge) { return IsUserAuthorizedEdgeType(edge.EdgeType()); }
private:
bool IsUserAuthorizedLabels(const std::vector<memgraph::storage::LabelId> &labels) const final {
return std::any_of(labels.begin(), labels.end(), [this](const auto label) {
return user_->GetFineGrainedAccessLabelPermissions().Has(dba_->LabelToName(label)) ==
@@ -278,7 +285,6 @@ class FineGrainedAccessChecker final : public memgraph::query::FineGrainedAccess
memgraph::auth::PermissionLevel::GRANT;
}
private:
memgraph::auth::User *user_;
DbAccessor *dba_;
};

View File

@@ -732,7 +732,6 @@ bool Expand::ExpandCursor::InitEdges(Frame &frame, ExecutionContext &context) {
auto &vertex = vertex_value.ValueVertex();
auto direction = self_.common_.direction;
if (direction == EdgeAtom::Direction::IN || direction == EdgeAtom::Direction::BOTH) {
if (self_.common_.existing_node) {
TypedValue &existing_node = frame[self_.common_.node_symbol];
@@ -740,12 +739,10 @@ bool Expand::ExpandCursor::InitEdges(Frame &frame, ExecutionContext &context) {
if (!existing_node.IsNull()) {
ExpectType(self_.common_.node_symbol, existing_node, TypedValue::Type::Vertex);
in_edges_.emplace(
UnwrapEdgesResult(vertex.InEdges(self_.view_, self_.common_.edge_types,
context.fine_grained_access_checker, existing_node.ValueVertex())));
UnwrapEdgesResult(vertex.InEdges(self_.view_, self_.common_.edge_types, existing_node.ValueVertex())));
}
} else {
in_edges_.emplace(UnwrapEdgesResult(
vertex.InEdges(self_.view_, self_.common_.edge_types, context.fine_grained_access_checker)));
in_edges_.emplace(UnwrapEdgesResult(vertex.InEdges(self_.view_, self_.common_.edge_types)));
}
if (in_edges_) {
in_edges_it_.emplace(in_edges_->begin());
@@ -759,12 +756,10 @@ bool Expand::ExpandCursor::InitEdges(Frame &frame, ExecutionContext &context) {
if (!existing_node.IsNull()) {
ExpectType(self_.common_.node_symbol, existing_node, TypedValue::Type::Vertex);
out_edges_.emplace(
UnwrapEdgesResult(vertex.OutEdges(self_.view_, self_.common_.edge_types,
context.fine_grained_access_checker, existing_node.ValueVertex())));
UnwrapEdgesResult(vertex.OutEdges(self_.view_, self_.common_.edge_types, existing_node.ValueVertex())));
}
} else {
out_edges_.emplace(UnwrapEdgesResult(
vertex.OutEdges(self_.view_, self_.common_.edge_types, context.fine_grained_access_checker)));
out_edges_.emplace(UnwrapEdgesResult(vertex.OutEdges(self_.view_, self_.common_.edge_types)));
}
if (out_edges_) {
out_edges_it_.emplace(out_edges_->begin());
@@ -821,8 +816,7 @@ namespace {
* @return See above.
*/
auto ExpandFromVertex(const VertexAccessor &vertex, EdgeAtom::Direction direction,
const std::vector<storage::EdgeTypeId> &edge_types, utils::MemoryResource *memory,
const ExecutionContext &context) {
const std::vector<storage::EdgeTypeId> &edge_types, utils::MemoryResource *memory) {
// wraps an EdgeAccessor into a pair <accessor, direction>
auto wrapper = [](EdgeAtom::Direction direction, auto &&edges) {
return iter::imap([direction](const auto &edge) { return std::make_pair(edge, direction); },
@@ -830,18 +824,16 @@ auto ExpandFromVertex(const VertexAccessor &vertex, EdgeAtom::Direction directio
};
storage::View view = storage::View::OLD;
utils::pmr::vector<decltype(wrapper(direction,
*vertex.InEdges(view, edge_types, context.fine_grained_access_checker)))>
chain_elements(memory);
utils::pmr::vector<decltype(wrapper(direction, *vertex.InEdges(view, edge_types)))> chain_elements(memory);
if (direction != EdgeAtom::Direction::OUT) {
auto edges = UnwrapEdgesResult(vertex.InEdges(view, edge_types, context.fine_grained_access_checker));
auto edges = UnwrapEdgesResult(vertex.InEdges(view, edge_types));
if (edges.begin() != edges.end()) {
chain_elements.emplace_back(wrapper(EdgeAtom::Direction::IN, std::move(edges)));
}
}
if (direction != EdgeAtom::Direction::IN) {
auto edges = UnwrapEdgesResult(vertex.OutEdges(view, edge_types, context.fine_grained_access_checker));
auto edges = UnwrapEdgesResult(vertex.OutEdges(view, edge_types));
if (edges.begin() != edges.end()) {
chain_elements.emplace_back(wrapper(EdgeAtom::Direction::OUT, std::move(edges)));
}
@@ -906,9 +898,8 @@ class ExpandVariableCursor : public Cursor {
// a stack of edge iterables corresponding to the level/depth of
// the expansion currently being Pulled
using ExpandEdges =
decltype(ExpandFromVertex(std::declval<VertexAccessor>(), EdgeAtom::Direction::IN, self_.common_.edge_types,
utils::NewDeleteResource(), std::declval<ExecutionContext>()));
using ExpandEdges = decltype(ExpandFromVertex(std::declval<VertexAccessor>(), EdgeAtom::Direction::IN,
self_.common_.edge_types, utils::NewDeleteResource()));
utils::pmr::vector<ExpandEdges> edges_;
// an iterator indicating the position in the corresponding edges_ element
@@ -949,8 +940,7 @@ class ExpandVariableCursor : public Cursor {
if (upper_bound_ > 0) {
auto *memory = edges_.get_allocator().GetMemoryResource();
edges_.emplace_back(
ExpandFromVertex(vertex, self_.common_.direction, self_.common_.edge_types, memory, context));
edges_.emplace_back(ExpandFromVertex(vertex, self_.common_.direction, self_.common_.edge_types, memory));
edges_it_.emplace_back(edges_.back().begin());
}
@@ -1050,7 +1040,7 @@ class ExpandVariableCursor : public Cursor {
if (upper_bound_ > static_cast<int64_t>(edges_.size())) {
auto *memory = edges_.get_allocator().GetMemoryResource();
edges_.emplace_back(
ExpandFromVertex(current_vertex, self_.common_.direction, self_.common_.edge_types, memory, context));
ExpandFromVertex(current_vertex, self_.common_.direction, self_.common_.edge_types, memory));
edges_it_.emplace_back(edges_.back().begin());
}
@@ -1193,8 +1183,7 @@ class STShortestPathCursor : public query::plan::Cursor {
for (const auto &vertex : source_frontier) {
if (self_.common_.direction != EdgeAtom::Direction::IN) {
auto out_edges = UnwrapEdgesResult(
vertex.OutEdges(storage::View::OLD, self_.common_.edge_types, context.fine_grained_access_checker));
auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : out_edges) {
if (ShouldExpand(edge.To(), edge, frame, evaluator) && !Contains(in_edge, edge.To())) {
in_edge.emplace(edge.To(), edge);
@@ -1211,8 +1200,7 @@ class STShortestPathCursor : public query::plan::Cursor {
}
}
if (self_.common_.direction != EdgeAtom::Direction::OUT) {
auto in_edges = UnwrapEdgesResult(
vertex.InEdges(storage::View::OLD, self_.common_.edge_types, context.fine_grained_access_checker));
auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : in_edges) {
if (ShouldExpand(edge.From(), edge, frame, evaluator) && !Contains(in_edge, edge.From())) {
in_edge.emplace(edge.From(), edge);
@@ -1243,8 +1231,7 @@ class STShortestPathCursor : public query::plan::Cursor {
// reversed.
for (const auto &vertex : sink_frontier) {
if (self_.common_.direction != EdgeAtom::Direction::OUT) {
auto out_edges = UnwrapEdgesResult(
vertex.OutEdges(storage::View::OLD, self_.common_.edge_types, context.fine_grained_access_checker));
auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : out_edges) {
if (ShouldExpand(vertex, edge, frame, evaluator) && !Contains(out_edge, edge.To())) {
out_edge.emplace(edge.To(), edge);
@@ -1261,8 +1248,7 @@ class STShortestPathCursor : public query::plan::Cursor {
}
}
if (self_.common_.direction != EdgeAtom::Direction::IN) {
auto in_edges = UnwrapEdgesResult(
vertex.InEdges(storage::View::OLD, self_.common_.edge_types, context.fine_grained_access_checker));
auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : in_edges) {
if (ShouldExpand(vertex, edge, frame, evaluator) && !Contains(out_edge, edge.From())) {
out_edge.emplace(edge.From(), edge);
@@ -1336,15 +1322,13 @@ class SingleSourceShortestPathCursor : public query::plan::Cursor {
// populates the to_visit_next_ structure with expansions
// from the given vertex. skips expansions that don't satisfy
// the "where" condition.
auto expand_from_vertex = [this, &expand_pair, &context](const auto &vertex) {
auto expand_from_vertex = [this, &expand_pair](const auto &vertex) {
if (self_.common_.direction != EdgeAtom::Direction::IN) {
auto out_edges = UnwrapEdgesResult(
vertex.OutEdges(storage::View::OLD, self_.common_.edge_types, context.fine_grained_access_checker));
auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : out_edges) expand_pair(edge, edge.To());
}
if (self_.common_.direction != EdgeAtom::Direction::OUT) {
auto in_edges = UnwrapEdgesResult(
vertex.InEdges(storage::View::OLD, self_.common_.edge_types, context.fine_grained_access_checker));
auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : in_edges) expand_pair(edge, edge.From());
}
};
@@ -1520,18 +1504,16 @@ class ExpandWeightedShortestPathCursor : public query::plan::Cursor {
// Populates the priority queue structure with expansions
// from the given vertex. skips expansions that don't satisfy
// the "where" condition.
auto expand_from_vertex = [this, &expand_pair, &context](const VertexAccessor &vertex, const TypedValue &weight,
int64_t depth) {
auto expand_from_vertex = [this, &expand_pair](const VertexAccessor &vertex, const TypedValue &weight,
int64_t depth) {
if (self_.common_.direction != EdgeAtom::Direction::IN) {
auto out_edges = UnwrapEdgesResult(
vertex.OutEdges(storage::View::OLD, self_.common_.edge_types, context.fine_grained_access_checker));
auto out_edges = UnwrapEdgesResult(vertex.OutEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : out_edges) {
expand_pair(edge, edge.To(), weight, depth);
}
}
if (self_.common_.direction != EdgeAtom::Direction::OUT) {
auto in_edges = UnwrapEdgesResult(
vertex.InEdges(storage::View::OLD, self_.common_.edge_types, context.fine_grained_access_checker));
auto in_edges = UnwrapEdgesResult(vertex.InEdges(storage::View::OLD, self_.common_.edge_types));
for (const auto &edge : in_edges) {
expand_pair(edge, edge.From(), weight, depth);
}

View File

@@ -403,9 +403,8 @@ uint64_t Storage::ReplicationServer::ReadAndApplyDelta(durability::BaseDecoder *
if (!from_vertex) throw utils::BasicException("Invalid transaction!");
auto to_vertex = transaction->FindVertex(delta.edge_create_delete.to_vertex, storage::View::NEW);
if (!to_vertex) throw utils::BasicException("Invalid transaction!");
auto edges =
from_vertex->OutEdges(storage::View::NEW, {transaction->NameToEdgeType(delta.edge_create_delete.edge_type)},
nullptr, &*to_vertex);
auto edges = from_vertex->OutEdges(
storage::View::NEW, {transaction->NameToEdgeType(delta.edge_create_delete.edge_type)}, &*to_vertex);
if (edges.HasError()) throw utils::BasicException("Invalid transaction!");
if (edges->size() != 1) throw utils::BasicException("Invalid transaction!");
auto &edge = (*edges)[0];

View File

@@ -13,7 +13,6 @@
#include <memory>
#include "query/fine_grained_access_checker.hpp"
#include "storage/v2/edge_accessor.hpp"
#include "storage/v2/id_types.hpp"
#include "storage/v2/indices.hpp"
@@ -340,9 +339,8 @@ Result<std::map<PropertyId, PropertyValue>> VertexAccessor::Properties(View view
return std::move(properties);
}
Result<std::vector<EdgeAccessor>> VertexAccessor::InEdges(
View view, const std::vector<storage::EdgeTypeId> &edge_types,
const query::FineGrainedAccessChecker *fine_grained_access_checker, const VertexAccessor *destination) const {
Result<std::vector<EdgeAccessor>> VertexAccessor::InEdges(View view, const std::vector<EdgeTypeId> &edge_types,
const VertexAccessor *destination) const {
MG_ASSERT(!destination || destination->transaction_ == transaction_, "Invalid accessor!");
bool exists = true;
bool deleted = false;
@@ -351,7 +349,7 @@ Result<std::vector<EdgeAccessor>> VertexAccessor::InEdges(
{
std::lock_guard<utils::SpinLock> guard(vertex_->lock);
deleted = vertex_->deleted;
if (!fine_grained_access_checker && !destination) {
if (edge_types.empty() && !destination) {
in_edges = vertex_->in_edges;
} else {
for (const auto &item : vertex_->in_edges) {
@@ -359,27 +357,19 @@ Result<std::vector<EdgeAccessor>> VertexAccessor::InEdges(
if (destination && from_vertex != destination->vertex_) continue;
if (!edge_types.empty() && std::find(edge_types.begin(), edge_types.end(), edge_type) == edge_types.end())
continue;
if (fine_grained_access_checker && (!fine_grained_access_checker->IsUserAuthorizedEdgeType(edge_type) ||
!fine_grained_access_checker->IsUserAuthorizedLabels(from_vertex->labels)))
continue;
in_edges.push_back(item);
}
}
delta = vertex_->delta;
}
ApplyDeltasForRead(
transaction_, delta, view,
[&exists, &deleted, &in_edges, &edge_types, &fine_grained_access_checker, &destination](const Delta &delta) {
transaction_, delta, view, [&exists, &deleted, &in_edges, &edge_types, &destination](const Delta &delta) {
switch (delta.action) {
case Delta::Action::ADD_IN_EDGE: {
if (destination && delta.vertex_edge.vertex != destination->vertex_) break;
if (!edge_types.empty() &&
std::find(edge_types.begin(), edge_types.end(), delta.vertex_edge.edge_type) == edge_types.end())
break;
if (fine_grained_access_checker &&
(!fine_grained_access_checker->IsUserAuthorizedEdgeType(delta.vertex_edge.edge_type) ||
!fine_grained_access_checker->IsUserAuthorizedLabels(delta.vertex_edge.vertex->labels)))
break;
// Add the edge because we don't see the removal.
std::tuple<EdgeTypeId, Vertex *, EdgeRef> link{delta.vertex_edge.edge_type, delta.vertex_edge.vertex,
delta.vertex_edge.edge};
@@ -393,10 +383,6 @@ Result<std::vector<EdgeAccessor>> VertexAccessor::InEdges(
if (!edge_types.empty() &&
std::find(edge_types.begin(), edge_types.end(), delta.vertex_edge.edge_type) == edge_types.end())
break;
if (fine_grained_access_checker &&
(!fine_grained_access_checker->IsUserAuthorizedEdgeType(delta.vertex_edge.edge_type) ||
!fine_grained_access_checker->IsUserAuthorizedLabels(delta.vertex_edge.vertex->labels)))
break;
// Remove the label because we don't see the addition.
std::tuple<EdgeTypeId, Vertex *, EdgeRef> link{delta.vertex_edge.edge_type, delta.vertex_edge.vertex,
delta.vertex_edge.edge};
@@ -433,9 +419,8 @@ Result<std::vector<EdgeAccessor>> VertexAccessor::InEdges(
return std::move(ret);
}
Result<std::vector<EdgeAccessor>> VertexAccessor::OutEdges(
View view, const std::vector<storage::EdgeTypeId> &edge_types,
const query::FineGrainedAccessChecker *fine_grained_access_checker, const VertexAccessor *destination) const {
Result<std::vector<EdgeAccessor>> VertexAccessor::OutEdges(View view, const std::vector<EdgeTypeId> &edge_types,
const VertexAccessor *destination) const {
MG_ASSERT(!destination || destination->transaction_ == transaction_, "Invalid accessor!");
bool exists = true;
bool deleted = false;
@@ -444,7 +429,7 @@ Result<std::vector<EdgeAccessor>> VertexAccessor::OutEdges(
{
std::lock_guard<utils::SpinLock> guard(vertex_->lock);
deleted = vertex_->deleted;
if (!fine_grained_access_checker && !destination) {
if (edge_types.empty() && !destination) {
out_edges = vertex_->out_edges;
} else {
for (const auto &item : vertex_->out_edges) {
@@ -452,27 +437,19 @@ Result<std::vector<EdgeAccessor>> VertexAccessor::OutEdges(
if (destination && to_vertex != destination->vertex_) continue;
if (!edge_types.empty() && std::find(edge_types.begin(), edge_types.end(), edge_type) == edge_types.end())
continue;
if (fine_grained_access_checker && (!fine_grained_access_checker->IsUserAuthorizedEdgeType(edge_type) ||
!fine_grained_access_checker->IsUserAuthorizedLabels(to_vertex->labels)))
continue;
out_edges.push_back(item);
}
}
delta = vertex_->delta;
}
ApplyDeltasForRead(
transaction_, delta, view,
[&exists, &deleted, &out_edges, &edge_types, &fine_grained_access_checker, &destination](const Delta &delta) {
transaction_, delta, view, [&exists, &deleted, &out_edges, &edge_types, &destination](const Delta &delta) {
switch (delta.action) {
case Delta::Action::ADD_OUT_EDGE: {
if (destination && delta.vertex_edge.vertex != destination->vertex_) break;
if (!edge_types.empty() &&
std::find(edge_types.begin(), edge_types.end(), delta.vertex_edge.edge_type) == edge_types.end())
break;
if (fine_grained_access_checker &&
(!fine_grained_access_checker->IsUserAuthorizedEdgeType(delta.vertex_edge.edge_type) ||
!fine_grained_access_checker->IsUserAuthorizedLabels(delta.vertex_edge.vertex->labels)))
break;
// Add the edge because we don't see the removal.
std::tuple<EdgeTypeId, Vertex *, EdgeRef> link{delta.vertex_edge.edge_type, delta.vertex_edge.vertex,
delta.vertex_edge.edge};
@@ -486,10 +463,6 @@ Result<std::vector<EdgeAccessor>> VertexAccessor::OutEdges(
if (!edge_types.empty() &&
std::find(edge_types.begin(), edge_types.end(), delta.vertex_edge.edge_type) == edge_types.end())
break;
if (fine_grained_access_checker &&
(!fine_grained_access_checker->IsUserAuthorizedEdgeType(delta.vertex_edge.edge_type) ||
!fine_grained_access_checker->IsUserAuthorizedLabels(delta.vertex_edge.vertex->labels)))
break;
// Remove the label because we don't see the addition.
std::tuple<EdgeTypeId, Vertex *, EdgeRef> link{delta.vertex_edge.edge_type, delta.vertex_edge.vertex,
delta.vertex_edge.edge};

View File

@@ -13,11 +13,11 @@
#include <optional>
#include "query/fine_grained_access_checker.hpp"
#include "storage/v2/vertex.hpp"
#include "storage/v2/config.hpp"
#include "storage/v2/result.hpp"
#include "storage/v2/transaction.hpp"
#include "storage/v2/vertex.hpp"
#include "storage/v2/view.hpp"
namespace memgraph::storage {
@@ -81,18 +81,14 @@ class VertexAccessor final {
/// @throw std::bad_alloc
/// @throw std::length_error if the resulting vector exceeds
/// std::vector::max_size().
Result<std::vector<EdgeAccessor>> InEdges(
View view, const std::vector<storage::EdgeTypeId> &edge_types = {},
const query::FineGrainedAccessChecker *fine_grained_access_checker = nullptr,
const VertexAccessor *destination = nullptr) const;
Result<std::vector<EdgeAccessor>> InEdges(View view, const std::vector<EdgeTypeId> &edge_types = {},
const VertexAccessor *destination = nullptr) const;
/// @throw std::bad_alloc
/// @throw std::length_error if the resulting vector exceeds
/// std::vector::max_size().
Result<std::vector<EdgeAccessor>> OutEdges(
View view, const std::vector<storage::EdgeTypeId> &edge_types = {},
const query::FineGrainedAccessChecker *fine_grained_access_checker = nullptr,
const VertexAccessor *destination = nullptr) const;
Result<std::vector<EdgeAccessor>> OutEdges(View view, const std::vector<EdgeTypeId> &edge_types = {},
const VertexAccessor *destination = nullptr) const;
Result<size_t> InDegree(View view) const;