Use ShardResult

This commit is contained in:
jbajic 2022-11-22 15:00:32 +01:00
parent f1e360469a
commit d82cfb349e
6 changed files with 71 additions and 70 deletions

View File

@ -25,9 +25,8 @@ namespace memgraph::storage::v3 {
SchemaValidator::SchemaValidator(Schemas &schemas, const NameIdMapper &name_id_mapper)
: schemas_{&schemas}, name_id_mapper_{&name_id_mapper} {}
std::optional<ShardError> SchemaValidator::ValidateVertexCreate(
LabelId primary_label, const std::vector<LabelId> &labels,
const std::vector<PropertyValue> &primary_properties) const {
ShardResult<void> SchemaValidator::ValidateVertexCreate(LabelId primary_label, const std::vector<LabelId> &labels,
const std::vector<PropertyValue> &primary_properties) const {
// Schema on primary label
const auto *schema = schemas_->GetSchema(primary_label);
if (schema == nullptr) {
@ -62,11 +61,11 @@ std::optional<ShardError> SchemaValidator::ValidateVertexCreate(
}
}
return std::nullopt;
return {};
}
std::optional<ShardError> SchemaValidator::ValidatePropertyUpdate(const LabelId primary_label,
const PropertyId property_id) const {
ShardResult<void> SchemaValidator::ValidatePropertyUpdate(const LabelId primary_label,
const PropertyId property_id) const {
// Verify existence of schema on primary label
const auto *schema = schemas_->GetSchema(primary_label);
MG_ASSERT(schema, "Cannot validate against non existing schema!");
@ -81,16 +80,16 @@ std::optional<ShardError> SchemaValidator::ValidatePropertyUpdate(const LabelId
name_id_mapper_->IdToName(schema_property->property_id.AsInt()),
name_id_mapper_->IdToName(primary_label.AsInt()));
}
return std::nullopt;
return {};
}
std::optional<ShardError> SchemaValidator::ValidateLabelUpdate(const LabelId label) const {
ShardResult<void> SchemaValidator::ValidateLabelUpdate(const LabelId label) const {
const auto *schema = schemas_->GetSchema(label);
if (schema) {
return SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_UPDATE_PRIMARY_LABEL, "Cannot add/remove primary label :{}",
name_id_mapper_->IdToName(label.AsInt()));
}
return std::nullopt;
return {};
}
const Schemas::Schema *SchemaValidator::GetSchema(LabelId label) const { return schemas_->GetSchema(label); }
@ -98,15 +97,15 @@ const Schemas::Schema *SchemaValidator::GetSchema(LabelId label) const { return
VertexValidator::VertexValidator(const SchemaValidator &schema_validator, const LabelId primary_label)
: schema_validator{&schema_validator}, primary_label_{primary_label} {}
std::optional<ShardError> VertexValidator::ValidatePropertyUpdate(PropertyId property_id) const {
ShardResult<void> VertexValidator::ValidatePropertyUpdate(PropertyId property_id) const {
return schema_validator->ValidatePropertyUpdate(primary_label_, property_id);
};
std::optional<ShardError> VertexValidator::ValidateAddLabel(LabelId label) const {
ShardResult<void> VertexValidator::ValidateAddLabel(LabelId label) const {
return schema_validator->ValidateLabelUpdate(label);
}
std::optional<ShardError> VertexValidator::ValidateRemoveLabel(LabelId label) const {
ShardResult<void> VertexValidator::ValidateRemoveLabel(LabelId label) const {
return schema_validator->ValidateLabelUpdate(label);
}

View File

@ -11,7 +11,6 @@
#pragma once
#include <optional>
#include <variant>
#include "storage/v2/result.hpp"
@ -27,13 +26,12 @@ class SchemaValidator {
public:
explicit SchemaValidator(Schemas &schemas, const NameIdMapper &name_id_mapper);
[[nodiscard]] std::optional<ShardError> ValidateVertexCreate(
LabelId primary_label, const std::vector<LabelId> &labels,
const std::vector<PropertyValue> &primary_properties) const;
[[nodiscard]] ShardResult<void> ValidateVertexCreate(LabelId primary_label, const std::vector<LabelId> &labels,
const std::vector<PropertyValue> &primary_properties) const;
[[nodiscard]] std::optional<ShardError> ValidatePropertyUpdate(LabelId primary_label, PropertyId property_id) const;
[[nodiscard]] ShardResult<void> ValidatePropertyUpdate(LabelId primary_label, PropertyId property_id) const;
[[nodiscard]] std::optional<ShardError> ValidateLabelUpdate(LabelId label) const;
[[nodiscard]] ShardResult<void> ValidateLabelUpdate(LabelId label) const;
const Schemas::Schema *GetSchema(LabelId label) const;
@ -45,11 +43,11 @@ class SchemaValidator {
struct VertexValidator {
explicit VertexValidator(const SchemaValidator &schema_validator, LabelId primary_label);
[[nodiscard]] std::optional<ShardError> ValidatePropertyUpdate(PropertyId property_id) const;
[[nodiscard]] ShardResult<void> ValidatePropertyUpdate(PropertyId property_id) const;
[[nodiscard]] std::optional<ShardError> ValidateAddLabel(LabelId label) const;
[[nodiscard]] ShardResult<void> ValidateAddLabel(LabelId label) const;
[[nodiscard]] std::optional<ShardError> ValidateRemoveLabel(LabelId label) const;
[[nodiscard]] ShardResult<void> ValidateRemoveLabel(LabelId label) const;
const SchemaValidator *schema_validator;

View File

@ -353,8 +353,8 @@ ShardResult<VertexAccessor> Shard::Accessor::CreateVertexAndValidate(
auto maybe_schema_violation =
GetSchemaValidator().ValidateVertexCreate(shard_->primary_label_, labels, primary_properties);
if (maybe_schema_violation) {
return {std::move(*maybe_schema_violation)};
if (maybe_schema_violation.HasError()) {
return {std::move(maybe_schema_violation.GetError())};
}
auto acc = shard_->vertices_.access();

View File

@ -330,11 +330,11 @@ ShardResult<msgs::ExpandOneResultRow> GetExpandOneResult(
auto v_acc = acc.FindVertex(primary_key, View::NEW);
msgs::Vertex source_vertex = {.id = src_vertex};
const auto maybe_secondary_labels = FillUpSourceVertexSecondaryLabels(v_acc, req);
auto maybe_secondary_labels = FillUpSourceVertexSecondaryLabels(v_acc, req);
if (maybe_secondary_labels.HasError()) {
return maybe_secondary_labels.GetError();
}
source_vertex.labels = *maybe_secondary_labels;
source_vertex.labels = std::move(*maybe_secondary_labels);
auto src_vertex_properties = FillUpSourceVertexProperties(v_acc, req, storage::v3::View::NEW, schema);

View File

@ -99,8 +99,8 @@ ShardResult<bool> VertexAccessor::AddLabel(LabelId label) {
}
ShardResult<bool> VertexAccessor::AddLabelAndValidate(LabelId label) {
if (const auto maybe_violation_error = vertex_validator_->ValidateAddLabel(label); maybe_violation_error) {
return {*maybe_violation_error};
if (const auto maybe_violation_error = vertex_validator_->ValidateAddLabel(label); maybe_violation_error.HasError()) {
return {maybe_violation_error.GetError()};
}
utils::MemoryTracker::OutOfMemoryExceptionEnabler oom_exception;
@ -135,8 +135,9 @@ ShardResult<bool> VertexAccessor::RemoveLabel(LabelId label) {
}
ShardResult<bool> VertexAccessor::RemoveLabelAndValidate(LabelId label) {
if (const auto maybe_violation_error = vertex_validator_->ValidateRemoveLabel(label); maybe_violation_error) {
return {*maybe_violation_error};
if (const auto maybe_violation_error = vertex_validator_->ValidateRemoveLabel(label);
maybe_violation_error.HasError()) {
return {maybe_violation_error.GetError()};
}
if (!PrepareForWrite(transaction_, vertex_)) return SHARD_ERROR(ErrorCode::SERIALIZATION_ERROR);
@ -332,8 +333,9 @@ ShardResult<void> VertexAccessor::CheckVertexExistence(View view) const {
}
ShardResult<PropertyValue> VertexAccessor::SetPropertyAndValidate(PropertyId property, const PropertyValue &value) {
if (auto maybe_violation_error = vertex_validator_->ValidatePropertyUpdate(property); maybe_violation_error) {
return {*maybe_violation_error};
if (auto maybe_violation_error = vertex_validator_->ValidatePropertyUpdate(property);
maybe_violation_error.HasError()) {
return {maybe_violation_error.GetError()};
}
utils::MemoryTracker::OutOfMemoryExceptionEnabler oom_exception;

View File

@ -14,7 +14,6 @@
#include <gtest/gtest.h>
#include <fmt/format.h>
#include <optional>
#include <string>
#include <vector>
@ -187,89 +186,92 @@ TEST_F(SchemaValidatorTest, TestSchemaValidateVertexCreate) {
// Validate against secondary label
{
const auto schema_violation = schema_validator.ValidateVertexCreate(NameToLabel("test"), {}, {PropertyValue(1)});
ASSERT_NE(schema_violation, std::nullopt);
EXPECT_EQ(*schema_violation, SHARD_ERROR(ErrorCode::SCHEMA_NO_SCHEMA_DEFINED_FOR_LABEL));
ASSERT_FALSE(schema_violation.HasError());
EXPECT_EQ(schema_violation.GetError(), SHARD_ERROR(ErrorCode::SCHEMA_NO_SCHEMA_DEFINED_FOR_LABEL));
}
{
const auto schema_violation = schema_validator.ValidateVertexCreate(label2, {}, {});
ASSERT_NE(schema_violation, std::nullopt);
EXPECT_EQ(*schema_violation, SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_PRIMARY_PROPERTIES_UNDEFINED));
ASSERT_FALSE(schema_violation.HasError());
EXPECT_EQ(schema_violation.GetError(), SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_PRIMARY_PROPERTIES_UNDEFINED));
}
// Validate wrong secondary label
{
const auto schema_violation = schema_validator.ValidateVertexCreate(label1, {label1}, {PropertyValue("test")});
ASSERT_NE(schema_violation, std::nullopt);
EXPECT_EQ(*schema_violation, SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_SECONDARY_LABEL_IS_PRIMARY));
ASSERT_FALSE(schema_violation.HasError());
EXPECT_EQ(schema_violation.GetError(), SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_SECONDARY_LABEL_IS_PRIMARY));
}
{
const auto schema_violation = schema_validator.ValidateVertexCreate(label1, {label2}, {PropertyValue("test")});
ASSERT_NE(schema_violation, std::nullopt);
EXPECT_EQ(*schema_violation, SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_SECONDARY_LABEL_IS_PRIMARY));
ASSERT_FALSE(schema_violation.HasError());
EXPECT_EQ(schema_violation.GetError(), SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_SECONDARY_LABEL_IS_PRIMARY));
}
// Validate wrong property type
{
const auto schema_violation = schema_validator.ValidateVertexCreate(label1, {}, {PropertyValue(1)});
ASSERT_NE(schema_violation, std::nullopt);
EXPECT_EQ(*schema_violation, SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_PROPERTY_WRONG_TYPE));
ASSERT_FALSE(schema_violation.HasError());
EXPECT_EQ(schema_violation.GetError(), SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_PROPERTY_WRONG_TYPE));
}
{
const auto schema_violation =
schema_validator.ValidateVertexCreate(label2, {}, {PropertyValue("test"), PropertyValue(12), PropertyValue(1)});
ASSERT_NE(schema_violation, std::nullopt);
EXPECT_EQ(*schema_violation, SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_PROPERTY_WRONG_TYPE));
ASSERT_FALSE(schema_violation.HasError());
EXPECT_EQ(schema_violation.GetError(), SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_PROPERTY_WRONG_TYPE));
}
{
const auto wrong_prop = PropertyValue(TemporalData(TemporalType::Date, 1234));
const auto schema_violation =
schema_validator.ValidateVertexCreate(label2, {}, {PropertyValue("test"), PropertyValue(12), wrong_prop});
ASSERT_NE(schema_violation, std::nullopt);
EXPECT_EQ(*schema_violation, SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_PROPERTY_WRONG_TYPE));
ASSERT_FALSE(schema_violation.HasError());
EXPECT_EQ(schema_violation.GetError(), SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_PROPERTY_WRONG_TYPE));
}
// Passing validations
EXPECT_EQ(schema_validator.ValidateVertexCreate(label1, {}, {PropertyValue("test")}), std::nullopt);
EXPECT_EQ(schema_validator.ValidateVertexCreate(label1, {NameToLabel("label3"), NameToLabel("label4")},
{PropertyValue("test")}),
std::nullopt);
EXPECT_EQ(schema_validator.ValidateVertexCreate(
label2, {},
{PropertyValue("test"), PropertyValue(122), PropertyValue(TemporalData(TemporalType::Duration, 1234))}),
std::nullopt);
EXPECT_EQ(schema_validator.ValidateVertexCreate(label2, {NameToLabel("label5"), NameToLabel("label6")},
{PropertyValue("test123"), PropertyValue(122221),
PropertyValue(TemporalData(TemporalType::Duration, 12344321))}),
std::nullopt);
EXPECT_FALSE(schema_validator.ValidateVertexCreate(label1, {}, {PropertyValue("test")}).HasError());
EXPECT_FALSE(
schema_validator
.ValidateVertexCreate(label1, {NameToLabel("label3"), NameToLabel("label4")}, {PropertyValue("test")})
.HasError());
EXPECT_FALSE(schema_validator
.ValidateVertexCreate(label2, {},
{PropertyValue("test"), PropertyValue(122),
PropertyValue(TemporalData(TemporalType::Duration, 1234))})
.HasError());
EXPECT_FALSE(schema_validator
.ValidateVertexCreate(label2, {NameToLabel("label5"), NameToLabel("label6")},
{PropertyValue("test123"), PropertyValue(122221),
PropertyValue(TemporalData(TemporalType::Duration, 12344321))})
.HasError());
}
TEST_F(SchemaValidatorTest, TestSchemaValidatePropertyUpdate) {
// Validate updating of primary key
{
const auto schema_violation = schema_validator.ValidatePropertyUpdate(label1, prop_string);
ASSERT_NE(schema_violation, std::nullopt);
EXPECT_EQ(*schema_violation, SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_UPDATE_PRIMARY_KEY));
ASSERT_FALSE(schema_violation.HasError());
EXPECT_EQ(schema_violation.GetError(), SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_UPDATE_PRIMARY_KEY));
}
{
const auto schema_violation = schema_validator.ValidatePropertyUpdate(label2, prop_duration);
ASSERT_NE(schema_violation, std::nullopt);
EXPECT_EQ(*schema_violation, SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_UPDATE_PRIMARY_KEY));
ASSERT_FALSE(schema_violation.HasError());
EXPECT_EQ(schema_violation.GetError(), SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_UPDATE_PRIMARY_KEY));
}
EXPECT_EQ(schema_validator.ValidatePropertyUpdate(label1, prop_int), std::nullopt);
EXPECT_EQ(schema_validator.ValidatePropertyUpdate(label1, prop_duration), std::nullopt);
EXPECT_EQ(schema_validator.ValidatePropertyUpdate(label2, NameToProperty("test")), std::nullopt);
EXPECT_FALSE(schema_validator.ValidatePropertyUpdate(label1, prop_int).HasError());
EXPECT_FALSE(schema_validator.ValidatePropertyUpdate(label1, prop_duration).HasError());
EXPECT_FALSE(schema_validator.ValidatePropertyUpdate(label2, NameToProperty("test")).HasError());
}
TEST_F(SchemaValidatorTest, TestSchemaValidatePropertyUpdateLabel) {
// Validate adding primary label
{
const auto schema_violation = schema_validator.ValidateLabelUpdate(label1);
ASSERT_NE(schema_violation, std::nullopt);
EXPECT_EQ(*schema_violation, SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_UPDATE_PRIMARY_LABEL));
ASSERT_FALSE(schema_violation.HasError());
EXPECT_EQ(schema_violation.GetError(), SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_UPDATE_PRIMARY_LABEL));
}
{
const auto schema_violation = schema_validator.ValidateLabelUpdate(label2);
ASSERT_NE(schema_violation, std::nullopt);
EXPECT_EQ(*schema_violation, SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_UPDATE_PRIMARY_LABEL));
ASSERT_FALSE(schema_violation.HasError());
EXPECT_EQ(schema_violation.GetError(), SHARD_ERROR(ErrorCode::SCHEMA_VERTEX_UPDATE_PRIMARY_LABEL));
}
EXPECT_EQ(schema_validator.ValidateLabelUpdate(NameToLabel("test")), std::nullopt);
EXPECT_FALSE(schema_validator.ValidateLabelUpdate(NameToLabel("test")).HasError());
}
} // namespace memgraph::storage::v3::tests