Remove primary label from vertex (#529)
- Remove the primary label from vertex - Pass vertex_validator instead of schema validator - Fix vertex ctors
This commit is contained in:
parent
e9f0360fb3
commit
a2a6a3855b
@ -14,6 +14,7 @@
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include "storage/v3/id_types.hpp"
|
||||
#include "storage/v3/isolation_level.hpp"
|
||||
#include "storage/v3/transaction.hpp"
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "storage/v3/edge_accessor.hpp"
|
||||
#include "storage/v3/edge_ref.hpp"
|
||||
#include "storage/v3/mvcc.hpp"
|
||||
#include "storage/v3/schema_validator.hpp"
|
||||
#include "storage/v3/schemas.hpp"
|
||||
#include "storage/v3/vertex_accessor.hpp"
|
||||
#include "storage/v3/vertices_skip_list.hpp"
|
||||
@ -636,7 +637,7 @@ void CreateSnapshot(Transaction *transaction, const std::filesystem::path &snaps
|
||||
const std::filesystem::path &wal_directory, uint64_t snapshot_retention_count,
|
||||
VerticesSkipList *vertices, utils::SkipList<Edge> *edges, NameIdMapper *name_id_mapper,
|
||||
Indices *indices, Constraints *constraints, Config::Items items,
|
||||
const SchemaValidator &schema_validator, const std::string &uuid, const std::string_view epoch_id,
|
||||
const VertexValidator &vertex_validator, const std::string &uuid, const std::string_view epoch_id,
|
||||
const std::deque<std::pair<std::string, uint64_t>> &epoch_history,
|
||||
utils::FileRetainer *file_retainer) {
|
||||
// Ensure that the storage directory exists.
|
||||
@ -718,7 +719,7 @@ void CreateSnapshot(Transaction *transaction, const std::filesystem::path &snaps
|
||||
// here.
|
||||
// TODO(jbajic) Fix snapshot with new schema rules
|
||||
auto ea = EdgeAccessor{edge_ref, EdgeTypeId::FromUint(0UL), nullptr, nullptr, transaction, indices, constraints,
|
||||
items, schema_validator};
|
||||
items, vertex_validator};
|
||||
|
||||
// Get edge data.
|
||||
auto maybe_props = ea.Properties(View::OLD);
|
||||
@ -746,7 +747,7 @@ void CreateSnapshot(Transaction *transaction, const std::filesystem::path &snaps
|
||||
auto acc = vertices->access();
|
||||
for (auto &lgo_vertex : acc) {
|
||||
// The visibility check is implemented for vertices so we use it here.
|
||||
auto va = VertexAccessor::Create(&lgo_vertex.vertex, transaction, indices, constraints, items, schema_validator,
|
||||
auto va = VertexAccessor::Create(&lgo_vertex.vertex, transaction, indices, constraints, items, vertex_validator,
|
||||
View::OLD);
|
||||
if (!va) continue;
|
||||
|
||||
|
@ -51,11 +51,11 @@ bool EdgeAccessor::IsVisible(const View view) const {
|
||||
}
|
||||
|
||||
VertexAccessor EdgeAccessor::FromVertex() const {
|
||||
return {from_vertex_, transaction_, indices_, constraints_, config_, *schema_validator_};
|
||||
return {from_vertex_, transaction_, indices_, constraints_, config_, *vertex_validator_};
|
||||
}
|
||||
|
||||
VertexAccessor EdgeAccessor::ToVertex() const {
|
||||
return {to_vertex_, transaction_, indices_, constraints_, config_, *schema_validator_};
|
||||
return {to_vertex_, transaction_, indices_, constraints_, config_, *vertex_validator_};
|
||||
}
|
||||
|
||||
Result<PropertyValue> EdgeAccessor::SetProperty(PropertyId property, const PropertyValue &value) {
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "storage/v3/edge_ref.hpp"
|
||||
|
||||
#include "storage/v3/config.hpp"
|
||||
#include "storage/v3/id_types.hpp"
|
||||
#include "storage/v3/result.hpp"
|
||||
#include "storage/v3/schema_validator.hpp"
|
||||
#include "storage/v3/transaction.hpp"
|
||||
@ -36,7 +37,7 @@ class EdgeAccessor final {
|
||||
public:
|
||||
EdgeAccessor(EdgeRef edge, EdgeTypeId edge_type, Vertex *from_vertex, Vertex *to_vertex, Transaction *transaction,
|
||||
Indices *indices, Constraints *constraints, Config::Items config,
|
||||
const SchemaValidator &schema_validator, bool for_deleted = false)
|
||||
const VertexValidator &vertex_validator, bool for_deleted = false)
|
||||
: edge_(edge),
|
||||
edge_type_(edge_type),
|
||||
from_vertex_(from_vertex),
|
||||
@ -45,7 +46,7 @@ class EdgeAccessor final {
|
||||
indices_(indices),
|
||||
constraints_(constraints),
|
||||
config_(config),
|
||||
schema_validator_{&schema_validator},
|
||||
vertex_validator_{&vertex_validator},
|
||||
for_deleted_(for_deleted) {}
|
||||
|
||||
/// @return true if the object is visible from the current transaction
|
||||
@ -94,7 +95,7 @@ class EdgeAccessor final {
|
||||
Indices *indices_;
|
||||
Constraints *constraints_;
|
||||
Config::Items config_;
|
||||
const SchemaValidator *schema_validator_;
|
||||
const VertexValidator *vertex_validator_;
|
||||
|
||||
// if the accessor was created for a deleted edge.
|
||||
// Accessor behaves differently for some methods based on this
|
||||
|
@ -13,9 +13,9 @@
|
||||
|
||||
#include <limits>
|
||||
|
||||
#include "storage/v3/id_types.hpp"
|
||||
#include "storage/v3/mvcc.hpp"
|
||||
#include "storage/v3/property_value.hpp"
|
||||
#include "storage/v3/schema_validator.hpp"
|
||||
#include "storage/v3/schemas.hpp"
|
||||
#include "utils/bound.hpp"
|
||||
#include "utils/logging.hpp"
|
||||
@ -327,7 +327,7 @@ void LabelIndex::RemoveObsoleteEntries(uint64_t oldest_active_start_timestamp) {
|
||||
LabelIndex::Iterable::Iterator::Iterator(Iterable *self, utils::SkipList<Entry>::Iterator index_iterator)
|
||||
: self_(self),
|
||||
index_iterator_(index_iterator),
|
||||
current_vertex_accessor_(nullptr, nullptr, nullptr, nullptr, self_->config_, *self_->schema_validator_),
|
||||
current_vertex_accessor_(nullptr, nullptr, nullptr, nullptr, self_->config_, *self_->vertex_validator_),
|
||||
current_vertex_(nullptr) {
|
||||
AdvanceUntilValid();
|
||||
}
|
||||
@ -346,7 +346,7 @@ void LabelIndex::Iterable::Iterator::AdvanceUntilValid() {
|
||||
if (CurrentVersionHasLabel(*index_iterator_->vertex, self_->label_, self_->transaction_, self_->view_)) {
|
||||
current_vertex_ = index_iterator_->vertex;
|
||||
current_vertex_accessor_ = VertexAccessor{current_vertex_, self_->transaction_, self_->indices_,
|
||||
self_->constraints_, self_->config_, *self_->schema_validator_};
|
||||
self_->constraints_, self_->config_, *self_->vertex_validator_};
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -354,7 +354,7 @@ void LabelIndex::Iterable::Iterator::AdvanceUntilValid() {
|
||||
|
||||
LabelIndex::Iterable::Iterable(utils::SkipList<Entry>::Accessor index_accessor, LabelId label, View view,
|
||||
Transaction *transaction, Indices *indices, Constraints *constraints,
|
||||
Config::Items config, const SchemaValidator &schema_validator)
|
||||
Config::Items config, const VertexValidator &vertex_validator)
|
||||
: index_accessor_(std::move(index_accessor)),
|
||||
label_(label),
|
||||
view_(view),
|
||||
@ -362,7 +362,7 @@ LabelIndex::Iterable::Iterable(utils::SkipList<Entry>::Accessor index_accessor,
|
||||
indices_(indices),
|
||||
constraints_(constraints),
|
||||
config_(config),
|
||||
schema_validator_(&schema_validator) {}
|
||||
vertex_validator_(&vertex_validator) {}
|
||||
|
||||
void LabelIndex::RunGC() {
|
||||
for (auto &index_entry : index_) {
|
||||
@ -480,7 +480,7 @@ void LabelPropertyIndex::RemoveObsoleteEntries(uint64_t oldest_active_start_time
|
||||
LabelPropertyIndex::Iterable::Iterator::Iterator(Iterable *self, utils::SkipList<Entry>::Iterator index_iterator)
|
||||
: self_(self),
|
||||
index_iterator_(index_iterator),
|
||||
current_vertex_accessor_(nullptr, nullptr, nullptr, nullptr, self_->config_, *self_->schema_validator_),
|
||||
current_vertex_accessor_(nullptr, nullptr, nullptr, nullptr, self_->config_, *self_->vertex_validator_),
|
||||
current_vertex_(nullptr) {
|
||||
AdvanceUntilValid();
|
||||
}
|
||||
@ -520,7 +520,7 @@ void LabelPropertyIndex::Iterable::Iterator::AdvanceUntilValid() {
|
||||
index_iterator_->value, self_->transaction_, self_->view_)) {
|
||||
current_vertex_ = index_iterator_->vertex;
|
||||
current_vertex_accessor_ = VertexAccessor(current_vertex_, self_->transaction_, self_->indices_,
|
||||
self_->constraints_, self_->config_, *self_->schema_validator_);
|
||||
self_->constraints_, self_->config_, *self_->vertex_validator_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -543,7 +543,7 @@ LabelPropertyIndex::Iterable::Iterable(utils::SkipList<Entry>::Accessor index_ac
|
||||
const std::optional<utils::Bound<PropertyValue>> &lower_bound,
|
||||
const std::optional<utils::Bound<PropertyValue>> &upper_bound, View view,
|
||||
Transaction *transaction, Indices *indices, Constraints *constraints,
|
||||
Config::Items config, const SchemaValidator &schema_validator)
|
||||
Config::Items config, const VertexValidator &vertex_validator)
|
||||
: index_accessor_(std::move(index_accessor)),
|
||||
label_(label),
|
||||
property_(property),
|
||||
@ -554,7 +554,7 @@ LabelPropertyIndex::Iterable::Iterable(utils::SkipList<Entry>::Accessor index_ac
|
||||
indices_(indices),
|
||||
constraints_(constraints),
|
||||
config_(config),
|
||||
schema_validator_(&schema_validator) {
|
||||
vertex_validator_(&vertex_validator) {
|
||||
// We have to fix the bounds that the user provided to us. If the user
|
||||
// provided only one bound we should make sure that only values of that type
|
||||
// are returned by the iterator. We ensure this by supplying either an
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
#include "storage/v3/config.hpp"
|
||||
#include "storage/v3/property_value.hpp"
|
||||
#include "storage/v3/schema_validator.hpp"
|
||||
#include "storage/v3/transaction.hpp"
|
||||
#include "storage/v3/vertex_accessor.hpp"
|
||||
#include "storage/v3/vertices_skip_list.hpp"
|
||||
@ -54,8 +53,8 @@ class LabelIndex {
|
||||
};
|
||||
|
||||
public:
|
||||
LabelIndex(Indices *indices, Constraints *constraints, Config::Items config, const SchemaValidator &schema_validator)
|
||||
: indices_(indices), constraints_(constraints), config_(config), schema_validator_{&schema_validator} {}
|
||||
LabelIndex(Indices *indices, Constraints *constraints, Config::Items config, const VertexValidator &vertex_validator)
|
||||
: indices_(indices), constraints_(constraints), config_(config), vertex_validator_{&vertex_validator} {}
|
||||
|
||||
/// @throw std::bad_alloc
|
||||
void UpdateOnAddLabel(LabelId label, Vertex *vertex, const Transaction &tx);
|
||||
@ -75,7 +74,7 @@ class LabelIndex {
|
||||
class Iterable {
|
||||
public:
|
||||
Iterable(utils::SkipList<Entry>::Accessor index_accessor, LabelId label, View view, Transaction *transaction,
|
||||
Indices *indices, Constraints *constraints, Config::Items config, const SchemaValidator &schema_validator);
|
||||
Indices *indices, Constraints *constraints, Config::Items config, const VertexValidator &vertex_validator);
|
||||
|
||||
class Iterator {
|
||||
public:
|
||||
@ -108,14 +107,14 @@ class LabelIndex {
|
||||
Indices *indices_;
|
||||
Constraints *constraints_;
|
||||
Config::Items config_;
|
||||
const SchemaValidator *schema_validator_;
|
||||
const VertexValidator *vertex_validator_;
|
||||
};
|
||||
|
||||
/// Returns an self with vertices visible from the given transaction.
|
||||
Iterable Vertices(LabelId label, View view, Transaction *transaction) {
|
||||
auto it = index_.find(label);
|
||||
MG_ASSERT(it != index_.end(), "Index for label {} doesn't exist", label.AsUint());
|
||||
return {it->second.access(), label, view, transaction, indices_, constraints_, config_, *schema_validator_};
|
||||
return {it->second.access(), label, view, transaction, indices_, constraints_, config_, *vertex_validator_};
|
||||
}
|
||||
|
||||
int64_t ApproximateVertexCount(LabelId label) {
|
||||
@ -133,7 +132,7 @@ class LabelIndex {
|
||||
Indices *indices_;
|
||||
Constraints *constraints_;
|
||||
Config::Items config_;
|
||||
const SchemaValidator *schema_validator_;
|
||||
const VertexValidator *vertex_validator_;
|
||||
};
|
||||
|
||||
class LabelPropertyIndex {
|
||||
@ -152,8 +151,8 @@ class LabelPropertyIndex {
|
||||
|
||||
public:
|
||||
LabelPropertyIndex(Indices *indices, Constraints *constraints, Config::Items config,
|
||||
const SchemaValidator &schema_validator)
|
||||
: indices_(indices), constraints_(constraints), config_(config), schema_validator_{&schema_validator} {}
|
||||
const VertexValidator &vertex_validator)
|
||||
: indices_(indices), constraints_(constraints), config_(config), vertex_validator_{&vertex_validator} {}
|
||||
|
||||
/// @throw std::bad_alloc
|
||||
void UpdateOnAddLabel(LabelId label, Vertex *vertex, const Transaction &tx);
|
||||
@ -177,7 +176,7 @@ class LabelPropertyIndex {
|
||||
Iterable(utils::SkipList<Entry>::Accessor index_accessor, LabelId label, PropertyId property,
|
||||
const std::optional<utils::Bound<PropertyValue>> &lower_bound,
|
||||
const std::optional<utils::Bound<PropertyValue>> &upper_bound, View view, Transaction *transaction,
|
||||
Indices *indices, Constraints *constraints, Config::Items config, const SchemaValidator &schema_validator);
|
||||
Indices *indices, Constraints *constraints, Config::Items config, const VertexValidator &vertex_validator);
|
||||
|
||||
class Iterator {
|
||||
public:
|
||||
@ -214,17 +213,17 @@ class LabelPropertyIndex {
|
||||
Indices *indices_;
|
||||
Constraints *constraints_;
|
||||
Config::Items config_;
|
||||
const SchemaValidator *schema_validator_;
|
||||
const VertexValidator *vertex_validator_;
|
||||
};
|
||||
|
||||
Iterable Vertices(LabelId label, PropertyId property, const std::optional<utils::Bound<PropertyValue>> &lower_bound,
|
||||
const std::optional<utils::Bound<PropertyValue>> &upper_bound, View view, Transaction *transaction,
|
||||
const SchemaValidator &schema_validator) {
|
||||
const VertexValidator &vertex_validator) {
|
||||
auto it = index_.find({label, property});
|
||||
MG_ASSERT(it != index_.end(), "Index for label {} and property {} doesn't exist", label.AsUint(),
|
||||
property.AsUint());
|
||||
return {it->second.access(), label, property, lower_bound, upper_bound, view,
|
||||
transaction, indices_, constraints_, config_, schema_validator};
|
||||
transaction, indices_, constraints_, config_, vertex_validator};
|
||||
}
|
||||
|
||||
int64_t ApproximateVertexCount(LabelId label, PropertyId property) const {
|
||||
@ -253,13 +252,13 @@ class LabelPropertyIndex {
|
||||
Indices *indices_;
|
||||
Constraints *constraints_;
|
||||
Config::Items config_;
|
||||
const SchemaValidator *schema_validator_;
|
||||
const VertexValidator *vertex_validator_;
|
||||
};
|
||||
|
||||
struct Indices {
|
||||
Indices(Constraints *constraints, Config::Items config, const SchemaValidator &schema_validator)
|
||||
: label_index(this, constraints, config, schema_validator),
|
||||
label_property_index(this, constraints, config, schema_validator) {}
|
||||
Indices(Constraints *constraints, Config::Items config, const VertexValidator &vertex_validator)
|
||||
: label_index(this, constraints, config, vertex_validator),
|
||||
label_property_index(this, constraints, config, vertex_validator) {}
|
||||
|
||||
// Disable copy and move because members hold pointer to `this`.
|
||||
Indices(const Indices &) = delete;
|
||||
|
@ -163,9 +163,9 @@ void Shard::ReplicationServer::SnapshotHandler(slk::Reader *req_reader, slk::Bui
|
||||
|
||||
shard_->constraints_ = Constraints();
|
||||
shard_->indices_.label_index =
|
||||
LabelIndex(&shard_->indices_, &shard_->constraints_, shard_->config_.items, shard_->schema_validator_);
|
||||
LabelIndex(&shard_->indices_, &shard_->constraints_, shard_->config_.items, shard_->vertex_validator_);
|
||||
shard_->indices_.label_property_index =
|
||||
LabelPropertyIndex(&shard_->indices_, &shard_->constraints_, shard_->config_.items, shard_->schema_validator_);
|
||||
LabelPropertyIndex(&shard_->indices_, &shard_->constraints_, shard_->config_.items, shard_->vertex_validator_);
|
||||
try {
|
||||
spdlog::debug("Loading snapshot");
|
||||
auto recovered_snapshot = durability::RecoveredSnapshot{};
|
||||
|
@ -103,4 +103,19 @@ SchemaValidator::SchemaValidator(Schemas &schemas) : schemas_{schemas} {}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
VertexValidator::VertexValidator(const SchemaValidator &schema_validator, const LabelId primary_label)
|
||||
: schema_validator{&schema_validator}, primary_label_{primary_label} {}
|
||||
|
||||
[[nodiscard]] std::optional<SchemaViolation> VertexValidator::ValidatePropertyUpdate(PropertyId property_id) const {
|
||||
return schema_validator->ValidatePropertyUpdate(primary_label_, property_id);
|
||||
};
|
||||
|
||||
[[nodiscard]] std::optional<SchemaViolation> VertexValidator::ValidateAddLabel(LabelId label) const {
|
||||
return schema_validator->ValidateLabelUpdate(label);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::optional<SchemaViolation> VertexValidator::ValidateRemoveLabel(LabelId label) const {
|
||||
return schema_validator->ValidateLabelUpdate(label);
|
||||
}
|
||||
|
||||
} // namespace memgraph::storage::v3
|
||||
|
@ -63,6 +63,20 @@ class SchemaValidator {
|
||||
Schemas &schemas_;
|
||||
};
|
||||
|
||||
struct VertexValidator {
|
||||
explicit VertexValidator(const SchemaValidator &schema_validator, LabelId primary_label);
|
||||
|
||||
[[nodiscard]] std::optional<SchemaViolation> ValidatePropertyUpdate(PropertyId property_id) const;
|
||||
|
||||
[[nodiscard]] std::optional<SchemaViolation> ValidateAddLabel(LabelId label) const;
|
||||
|
||||
[[nodiscard]] std::optional<SchemaViolation> ValidateRemoveLabel(LabelId label) const;
|
||||
|
||||
const SchemaValidator *schema_validator;
|
||||
|
||||
LabelId primary_label_;
|
||||
};
|
||||
|
||||
template <typename TValue>
|
||||
using ResultSchema = utils::BasicResult<std::variant<SchemaViolation, Error>, TValue>;
|
||||
|
||||
|
@ -70,9 +70,9 @@ void InsertVertexPKIntoList(auto &container, const PrimaryKey &primary_key) { co
|
||||
|
||||
auto AdvanceToVisibleVertex(VerticesSkipList::Iterator it, VerticesSkipList::Iterator end,
|
||||
std::optional<VertexAccessor> *vertex, Transaction *tx, View view, Indices *indices,
|
||||
Constraints *constraints, Config::Items config, const SchemaValidator &schema_validator) {
|
||||
Constraints *constraints, Config::Items config, const VertexValidator &vertex_validator) {
|
||||
while (it != end) {
|
||||
*vertex = VertexAccessor::Create(&it->vertex, tx, indices, constraints, config, schema_validator, view);
|
||||
*vertex = VertexAccessor::Create(&it->vertex, tx, indices, constraints, config, vertex_validator, view);
|
||||
if (!*vertex) {
|
||||
++it;
|
||||
continue;
|
||||
@ -85,14 +85,14 @@ auto AdvanceToVisibleVertex(VerticesSkipList::Iterator it, VerticesSkipList::Ite
|
||||
AllVerticesIterable::Iterator::Iterator(AllVerticesIterable *self, VerticesSkipList::Iterator it)
|
||||
: self_(self),
|
||||
it_(AdvanceToVisibleVertex(it, self->vertices_accessor_.end(), &self->vertex_, self->transaction_, self->view_,
|
||||
self->indices_, self_->constraints_, self->config_, *self_->schema_validator_)) {}
|
||||
self->indices_, self_->constraints_, self->config_, *self_->vertex_validator_)) {}
|
||||
|
||||
VertexAccessor AllVerticesIterable::Iterator::operator*() const { return *self_->vertex_; }
|
||||
|
||||
AllVerticesIterable::Iterator &AllVerticesIterable::Iterator::operator++() {
|
||||
++it_;
|
||||
it_ = AdvanceToVisibleVertex(it_, self_->vertices_accessor_.end(), &self_->vertex_, self_->transaction_, self_->view_,
|
||||
self_->indices_, self_->constraints_, self_->config_, *self_->schema_validator_);
|
||||
self_->indices_, self_->constraints_, self_->config_, *self_->vertex_validator_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -321,7 +321,8 @@ Shard::Shard(const LabelId primary_label, const PrimaryKey min_primary_key,
|
||||
min_primary_key_{min_primary_key},
|
||||
max_primary_key_{max_primary_key},
|
||||
schema_validator_{schemas_},
|
||||
indices_{&constraints_, config.items, schema_validator_},
|
||||
vertex_validator_{schema_validator_, primary_label},
|
||||
indices_{&constraints_, config.items, vertex_validator_},
|
||||
isolation_level_{config.transaction.isolation_level},
|
||||
config_{config},
|
||||
snapshot_directory_{config_.durability.storage_directory / durability::kSnapshotDirectory},
|
||||
@ -496,10 +497,10 @@ ResultSchema<VertexAccessor> Shard::Accessor::CreateVertexAndValidate(
|
||||
}
|
||||
auto acc = shard_->vertices_.access();
|
||||
auto *delta = CreateDeleteObjectDelta(&transaction_);
|
||||
auto [it, inserted] = acc.insert({Vertex{delta, primary_label, primary_properties}});
|
||||
auto [it, inserted] = acc.insert({Vertex{delta, primary_properties}});
|
||||
|
||||
VertexAccessor vertex_acc{&it->vertex, &transaction_, &shard_->indices_,
|
||||
&shard_->constraints_, config_, shard_->schema_validator_};
|
||||
&shard_->constraints_, config_, shard_->vertex_validator_};
|
||||
MG_ASSERT(inserted, "The vertex must be inserted here!");
|
||||
MG_ASSERT(it != acc.end(), "Invalid Vertex accessor!");
|
||||
|
||||
@ -529,7 +530,7 @@ std::optional<VertexAccessor> Shard::Accessor::FindVertex(std::vector<PropertyVa
|
||||
return std::nullopt;
|
||||
}
|
||||
return VertexAccessor::Create(&it->vertex, &transaction_, &shard_->indices_, &shard_->constraints_, config_,
|
||||
shard_->schema_validator_, view);
|
||||
shard_->vertex_validator_, view);
|
||||
}
|
||||
|
||||
Result<std::optional<VertexAccessor>> Shard::Accessor::DeleteVertex(VertexAccessor *vertex) {
|
||||
@ -550,7 +551,7 @@ Result<std::optional<VertexAccessor>> Shard::Accessor::DeleteVertex(VertexAccess
|
||||
vertex_ptr->deleted = true;
|
||||
|
||||
return std::make_optional<VertexAccessor>(vertex_ptr, &transaction_, &shard_->indices_, &shard_->constraints_,
|
||||
config_, shard_->schema_validator_, true);
|
||||
config_, shard_->vertex_validator_, true);
|
||||
}
|
||||
|
||||
Result<std::optional<std::pair<VertexAccessor, std::vector<EdgeAccessor>>>> Shard::Accessor::DetachDeleteVertex(
|
||||
@ -578,7 +579,7 @@ Result<std::optional<std::pair<VertexAccessor, std::vector<EdgeAccessor>>>> Shar
|
||||
for (const auto &item : in_edges) {
|
||||
auto [edge_type, from_vertex, edge] = item;
|
||||
EdgeAccessor e(edge, edge_type, from_vertex, vertex_ptr, &transaction_, &shard_->indices_, &shard_->constraints_,
|
||||
config_, shard_->schema_validator_);
|
||||
config_, shard_->vertex_validator_);
|
||||
auto ret = DeleteEdge(&e);
|
||||
if (ret.HasError()) {
|
||||
MG_ASSERT(ret.GetError() == Error::SERIALIZATION_ERROR, "Invalid database state!");
|
||||
@ -592,7 +593,7 @@ Result<std::optional<std::pair<VertexAccessor, std::vector<EdgeAccessor>>>> Shar
|
||||
for (const auto &item : out_edges) {
|
||||
auto [edge_type, to_vertex, edge] = item;
|
||||
EdgeAccessor e(edge, edge_type, vertex_ptr, to_vertex, &transaction_, &shard_->indices_, &shard_->constraints_,
|
||||
config_, shard_->schema_validator_);
|
||||
config_, shard_->vertex_validator_);
|
||||
auto ret = DeleteEdge(&e);
|
||||
if (ret.HasError()) {
|
||||
MG_ASSERT(ret.GetError() == Error::SERIALIZATION_ERROR, "Invalid database state!");
|
||||
@ -616,7 +617,7 @@ Result<std::optional<std::pair<VertexAccessor, std::vector<EdgeAccessor>>>> Shar
|
||||
vertex_ptr->deleted = true;
|
||||
|
||||
return std::make_optional<ReturnType>(VertexAccessor{vertex_ptr, &transaction_, &shard_->indices_,
|
||||
&shard_->constraints_, config_, shard_->schema_validator_, true},
|
||||
&shard_->constraints_, config_, shard_->vertex_validator_, true},
|
||||
std::move(deleted_edges));
|
||||
}
|
||||
|
||||
@ -662,7 +663,7 @@ Result<EdgeAccessor> Shard::Accessor::CreateEdge(VertexAccessor *from, VertexAcc
|
||||
++shard_->edge_count_;
|
||||
|
||||
return EdgeAccessor(edge, edge_type, from_vertex, to_vertex, &transaction_, &shard_->indices_, &shard_->constraints_,
|
||||
config_, shard_->schema_validator_);
|
||||
config_, shard_->vertex_validator_);
|
||||
}
|
||||
|
||||
Result<EdgeAccessor> Shard::Accessor::CreateEdge(VertexAccessor *from, VertexAccessor *to, EdgeTypeId edge_type,
|
||||
@ -715,7 +716,7 @@ Result<EdgeAccessor> Shard::Accessor::CreateEdge(VertexAccessor *from, VertexAcc
|
||||
++shard_->edge_count_;
|
||||
|
||||
return EdgeAccessor(edge, edge_type, from_vertex, to_vertex, &transaction_, &shard_->indices_, &shard_->constraints_,
|
||||
config_, shard_->schema_validator_);
|
||||
config_, shard_->vertex_validator_);
|
||||
}
|
||||
|
||||
Result<std::optional<EdgeAccessor>> Shard::Accessor::DeleteEdge(EdgeAccessor *edge) {
|
||||
@ -783,7 +784,7 @@ Result<std::optional<EdgeAccessor>> Shard::Accessor::DeleteEdge(EdgeAccessor *ed
|
||||
--shard_->edge_count_;
|
||||
|
||||
return std::make_optional<EdgeAccessor>(edge_ref, edge_type, from_vertex, to_vertex, &transaction_, &shard_->indices_,
|
||||
&shard_->constraints_, config_, shard_->schema_validator_, true);
|
||||
&shard_->constraints_, config_, shard_->vertex_validator_, true);
|
||||
}
|
||||
|
||||
const std::string &Shard::Accessor::LabelToName(LabelId label) const { return shard_->LabelToName(label); }
|
||||
@ -1208,20 +1209,20 @@ VerticesIterable Shard::Accessor::Vertices(LabelId label, View view) {
|
||||
|
||||
VerticesIterable Shard::Accessor::Vertices(LabelId label, PropertyId property, View view) {
|
||||
return VerticesIterable(shard_->indices_.label_property_index.Vertices(
|
||||
label, property, std::nullopt, std::nullopt, view, &transaction_, shard_->schema_validator_));
|
||||
label, property, std::nullopt, std::nullopt, view, &transaction_, shard_->vertex_validator_));
|
||||
}
|
||||
|
||||
VerticesIterable Shard::Accessor::Vertices(LabelId label, PropertyId property, const PropertyValue &value, View view) {
|
||||
return VerticesIterable(shard_->indices_.label_property_index.Vertices(
|
||||
label, property, utils::MakeBoundInclusive(value), utils::MakeBoundInclusive(value), view, &transaction_,
|
||||
shard_->schema_validator_));
|
||||
shard_->vertex_validator_));
|
||||
}
|
||||
|
||||
VerticesIterable Shard::Accessor::Vertices(LabelId label, PropertyId property,
|
||||
const std::optional<utils::Bound<PropertyValue>> &lower_bound,
|
||||
const std::optional<utils::Bound<PropertyValue>> &upper_bound, View view) {
|
||||
return VerticesIterable(shard_->indices_.label_property_index.Vertices(
|
||||
label, property, lower_bound, upper_bound, view, &transaction_, shard_->schema_validator_));
|
||||
label, property, lower_bound, upper_bound, view, &transaction_, shard_->vertex_validator_));
|
||||
}
|
||||
|
||||
Transaction Shard::CreateTransaction(IsolationLevel isolation_level) {
|
||||
|
@ -79,7 +79,7 @@ class AllVerticesIterable final {
|
||||
Indices *indices_;
|
||||
Constraints *constraints_;
|
||||
Config::Items config_;
|
||||
const SchemaValidator *schema_validator_;
|
||||
const VertexValidator *vertex_validator_;
|
||||
const Schemas *schemas_;
|
||||
std::optional<VertexAccessor> vertex_;
|
||||
|
||||
@ -102,14 +102,14 @@ class AllVerticesIterable final {
|
||||
|
||||
AllVerticesIterable(VerticesSkipList::Accessor vertices_accessor, Transaction *transaction, View view,
|
||||
Indices *indices, Constraints *constraints, Config::Items config,
|
||||
const SchemaValidator &schema_validator)
|
||||
const VertexValidator &vertex_validator)
|
||||
: vertices_accessor_(std::move(vertices_accessor)),
|
||||
transaction_(transaction),
|
||||
view_(view),
|
||||
indices_(indices),
|
||||
constraints_(constraints),
|
||||
config_(config),
|
||||
schema_validator_{&schema_validator} {}
|
||||
vertex_validator_{&vertex_validator} {}
|
||||
|
||||
Iterator begin() { return {this, vertices_accessor_.begin()}; }
|
||||
Iterator end() { return {this, vertices_accessor_.end()}; }
|
||||
@ -246,7 +246,7 @@ class Shard final {
|
||||
VerticesIterable Vertices(View view) {
|
||||
return VerticesIterable(AllVerticesIterable(shard_->vertices_.access(), &transaction_, view, &shard_->indices_,
|
||||
&shard_->constraints_, shard_->config_.items,
|
||||
shard_->schema_validator_));
|
||||
shard_->vertex_validator_));
|
||||
}
|
||||
|
||||
VerticesIterable Vertices(LabelId label, View view);
|
||||
@ -519,6 +519,7 @@ class Shard final {
|
||||
uint64_t edge_count_{0};
|
||||
|
||||
SchemaValidator schema_validator_;
|
||||
VertexValidator vertex_validator_;
|
||||
Constraints constraints_;
|
||||
Indices indices_;
|
||||
Schemas schemas_;
|
||||
|
@ -28,19 +28,11 @@
|
||||
namespace memgraph::storage::v3 {
|
||||
|
||||
struct Vertex {
|
||||
Vertex(Delta *delta, LabelId primary_label, const std::vector<PropertyValue> &primary_properties)
|
||||
: primary_label{primary_label}, keys{primary_properties}, delta{delta} {
|
||||
Vertex(Delta *delta, const std::vector<PropertyValue> &primary_properties) : keys{primary_properties}, delta{delta} {
|
||||
MG_ASSERT(delta == nullptr || delta->action == Delta::Action::DELETE_OBJECT,
|
||||
"Vertex must be created with an initial DELETE_OBJECT delta!");
|
||||
}
|
||||
|
||||
Vertex(LabelId primary_label, const std::vector<PropertyValue> &primary_properties)
|
||||
: primary_label{primary_label}, keys(primary_properties) {
|
||||
MG_ASSERT(delta == nullptr || delta->action == Delta::Action::DELETE_OBJECT,
|
||||
"Vertex must be created with an initial DELETE_OBJECT delta!");
|
||||
}
|
||||
|
||||
LabelId primary_label;
|
||||
KeyStore keys;
|
||||
|
||||
std::vector<LabelId> labels;
|
||||
@ -57,8 +49,6 @@ struct Vertex {
|
||||
|
||||
static_assert(alignof(Vertex) >= 8, "The Vertex should be aligned to at least 8!");
|
||||
|
||||
inline bool VertexHasLabel(const Vertex &vertex, const LabelId label) {
|
||||
return vertex.primary_label == label || utils::Contains(vertex.labels, label);
|
||||
}
|
||||
inline bool VertexHasLabel(const Vertex &vertex, const LabelId label) { return utils::Contains(vertex.labels, label); }
|
||||
|
||||
} // namespace memgraph::storage::v3
|
||||
|
@ -64,12 +64,12 @@ std::pair<bool, bool> IsVisible(Vertex *vertex, Transaction *transaction, View v
|
||||
|
||||
std::optional<VertexAccessor> VertexAccessor::Create(Vertex *vertex, Transaction *transaction, Indices *indices,
|
||||
Constraints *constraints, Config::Items config,
|
||||
const SchemaValidator &schema_validator, View view) {
|
||||
const VertexValidator &vertex_validator, View view) {
|
||||
if (const auto [exists, deleted] = detail::IsVisible(vertex, transaction, view); !exists || deleted) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return VertexAccessor{vertex, transaction, indices, constraints, config, schema_validator};
|
||||
return VertexAccessor{vertex, transaction, indices, constraints, config, vertex_validator};
|
||||
}
|
||||
|
||||
bool VertexAccessor::IsVisible(View view) const {
|
||||
@ -96,7 +96,7 @@ Result<bool> VertexAccessor::AddLabel(LabelId label) {
|
||||
}
|
||||
|
||||
ResultSchema<bool> VertexAccessor::AddLabelAndValidate(LabelId label) {
|
||||
if (const auto maybe_violation_error = vertex_validator_.ValidateAddLabel(label); maybe_violation_error) {
|
||||
if (const auto maybe_violation_error = vertex_validator_->ValidateAddLabel(label); maybe_violation_error) {
|
||||
return {*maybe_violation_error};
|
||||
}
|
||||
utils::MemoryTracker::OutOfMemoryExceptionEnabler oom_exception;
|
||||
@ -132,7 +132,7 @@ Result<bool> VertexAccessor::RemoveLabel(LabelId label) {
|
||||
}
|
||||
|
||||
ResultSchema<bool> VertexAccessor::RemoveLabelAndValidate(LabelId label) {
|
||||
if (const auto maybe_violation_error = vertex_validator_.ValidateRemoveLabel(label); maybe_violation_error) {
|
||||
if (const auto maybe_violation_error = vertex_validator_->ValidateRemoveLabel(label); maybe_violation_error) {
|
||||
return {*maybe_violation_error};
|
||||
}
|
||||
|
||||
@ -157,7 +157,7 @@ Result<bool> VertexAccessor::HasLabel(LabelId label, View view) const {
|
||||
Delta *delta = nullptr;
|
||||
{
|
||||
deleted = vertex_->deleted;
|
||||
has_label = VertexHasLabel(*vertex_, label);
|
||||
has_label = label == vertex_validator_->primary_label_ || VertexHasLabel(*vertex_, label);
|
||||
delta = vertex_->delta;
|
||||
}
|
||||
ApplyDeltasForRead(transaction_, delta, view, [&exists, &deleted, &has_label, label](const Delta &delta) {
|
||||
@ -227,7 +227,7 @@ Result<LabelId> VertexAccessor::PrimaryLabel(const View view) const {
|
||||
});
|
||||
if (!exists) return Error::NONEXISTENT_OBJECT;
|
||||
if (!for_deleted_ && deleted) return Error::DELETED_OBJECT;
|
||||
return vertex_->primary_label;
|
||||
return vertex_validator_->primary_label_;
|
||||
}
|
||||
|
||||
Result<PrimaryKey> VertexAccessor::PrimaryKey(const View view) const {
|
||||
@ -338,7 +338,7 @@ Result<PropertyValue> VertexAccessor::SetProperty(PropertyId property, const Pro
|
||||
}
|
||||
|
||||
ResultSchema<PropertyValue> VertexAccessor::SetPropertyAndValidate(PropertyId property, const PropertyValue &value) {
|
||||
if (auto maybe_violation_error = vertex_validator_.ValidatePropertyUpdate(property); maybe_violation_error) {
|
||||
if (auto maybe_violation_error = vertex_validator_->ValidatePropertyUpdate(property); maybe_violation_error) {
|
||||
return {*maybe_violation_error};
|
||||
}
|
||||
utils::MemoryTracker::OutOfMemoryExceptionEnabler oom_exception;
|
||||
@ -546,7 +546,7 @@ Result<std::vector<EdgeAccessor>> VertexAccessor::InEdges(View view, const std::
|
||||
for (const auto &item : in_edges) {
|
||||
const auto &[edge_type, from_vertex, edge] = item;
|
||||
ret.emplace_back(edge, edge_type, from_vertex, vertex_, transaction_, indices_, constraints_, config_,
|
||||
*vertex_validator_.schema_validator);
|
||||
*vertex_validator_);
|
||||
}
|
||||
return std::move(ret);
|
||||
}
|
||||
@ -626,7 +626,7 @@ Result<std::vector<EdgeAccessor>> VertexAccessor::OutEdges(View view, const std:
|
||||
for (const auto &item : out_edges) {
|
||||
const auto &[edge_type, to_vertex, edge] = item;
|
||||
ret.emplace_back(edge, edge_type, vertex_, to_vertex, transaction_, indices_, constraints_, config_,
|
||||
*vertex_validator_.schema_validator);
|
||||
*vertex_validator_);
|
||||
}
|
||||
return std::move(ret);
|
||||
}
|
||||
@ -705,21 +705,4 @@ Result<size_t> VertexAccessor::OutDegree(View view) const {
|
||||
return degree;
|
||||
}
|
||||
|
||||
VertexAccessor::VertexValidator::VertexValidator(const SchemaValidator &schema_validator, const Vertex *vertex)
|
||||
: schema_validator{&schema_validator}, vertex_{vertex} {}
|
||||
|
||||
[[nodiscard]] std::optional<SchemaViolation> VertexAccessor::VertexValidator::ValidatePropertyUpdate(
|
||||
PropertyId property_id) const {
|
||||
MG_ASSERT(vertex_ != nullptr, "Cannot validate vertex which is nullptr");
|
||||
return schema_validator->ValidatePropertyUpdate(vertex_->primary_label, property_id);
|
||||
};
|
||||
|
||||
[[nodiscard]] std::optional<SchemaViolation> VertexAccessor::VertexValidator::ValidateAddLabel(LabelId label) const {
|
||||
return schema_validator->ValidateLabelUpdate(label);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::optional<SchemaViolation> VertexAccessor::VertexValidator::ValidateRemoveLabel(LabelId label) const {
|
||||
return schema_validator->ValidateLabelUpdate(label);
|
||||
}
|
||||
|
||||
} // namespace memgraph::storage::v3
|
||||
|
@ -31,39 +31,24 @@ struct Constraints;
|
||||
|
||||
class VertexAccessor final {
|
||||
private:
|
||||
struct VertexValidator {
|
||||
// TODO(jbajic) Beware since vertex is pointer it will be accessed even as nullptr
|
||||
explicit VertexValidator(const SchemaValidator &schema_validator, const Vertex *vertex);
|
||||
|
||||
[[nodiscard]] std::optional<SchemaViolation> ValidatePropertyUpdate(PropertyId property_id) const;
|
||||
|
||||
[[nodiscard]] std::optional<SchemaViolation> ValidateAddLabel(LabelId label) const;
|
||||
|
||||
[[nodiscard]] std::optional<SchemaViolation> ValidateRemoveLabel(LabelId label) const;
|
||||
|
||||
const SchemaValidator *schema_validator;
|
||||
|
||||
private:
|
||||
const Vertex *vertex_;
|
||||
};
|
||||
friend class Shard;
|
||||
|
||||
public:
|
||||
// Be careful when using VertexAccessor since it can be instantiated with
|
||||
// nullptr values
|
||||
VertexAccessor(Vertex *vertex, Transaction *transaction, Indices *indices, Constraints *constraints,
|
||||
Config::Items config, const SchemaValidator &schema_validator, bool for_deleted = false)
|
||||
Config::Items config, const VertexValidator &vertex_validator, bool for_deleted = false)
|
||||
: vertex_(vertex),
|
||||
transaction_(transaction),
|
||||
indices_(indices),
|
||||
constraints_(constraints),
|
||||
config_(config),
|
||||
vertex_validator_{schema_validator, vertex},
|
||||
vertex_validator_{&vertex_validator},
|
||||
for_deleted_(for_deleted) {}
|
||||
|
||||
static std::optional<VertexAccessor> Create(Vertex *vertex, Transaction *transaction, Indices *indices,
|
||||
Constraints *constraints, Config::Items config,
|
||||
const SchemaValidator &schema_validator, View view);
|
||||
const VertexValidator &vertex_validator, View view);
|
||||
|
||||
/// @return true if the object is visible from the current transaction
|
||||
bool IsVisible(View view) const;
|
||||
@ -148,7 +133,7 @@ class VertexAccessor final {
|
||||
Indices *indices_;
|
||||
Constraints *constraints_;
|
||||
Config::Items config_;
|
||||
VertexValidator vertex_validator_;
|
||||
const VertexValidator *vertex_validator_;
|
||||
|
||||
// if the accessor was created for a deleted vertex.
|
||||
// Accessor behaves differently for some methods based on this
|
||||
|
Loading…
Reference in New Issue
Block a user