Removed storage changes
This commit is contained in:
@@ -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
|
||||
@@ -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_); }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user