From 07032887a4c915623d27d8e07658ac1fbdfc7b29 Mon Sep 17 00:00:00 2001 From: jbajic Date: Tue, 15 Nov 2022 18:24:28 +0100 Subject: [PATCH] Adapt mg-expr --- src/expr/interpret/eval.hpp | 65 ++++++++++++++------------------ src/query/v2/bindings/eval.hpp | 11 ++++-- src/storage/v3/bindings/eval.hpp | 3 +- 3 files changed, 37 insertions(+), 42 deletions(-) diff --git a/src/expr/interpret/eval.hpp b/src/expr/interpret/eval.hpp index 70127c023..d105eeefb 100644 --- a/src/expr/interpret/eval.hpp +++ b/src/expr/interpret/eval.hpp @@ -32,7 +32,7 @@ struct StorageTag {}; struct QueryEngineTag {}; template + typename PropertyValue, typename ConvFunctor, typename TError, typename Tag = StorageTag> class ExpressionEvaluator : public ExpressionVisitor { public: ExpressionEvaluator(Frame *frame, const SymbolTable &symbol_table, const EvaluationContext &ctx, @@ -100,6 +100,27 @@ class ExpressionEvaluator : public ExpressionVisitor { #undef BINARY_OPERATOR_VISITOR #undef UNARY_OPERATOR_VISITOR + void HandleShardError(TError &shard_error, const std::string_view accessed_object) { + switch (shard_error) { + case TError::DELETED_OBJECT: + throw ExpressionRuntimeException("Trying to access {} on a deleted object.", accessed_object); + case TError::NONEXISTENT_OBJECT: + throw ExpressionRuntimeException("Trying to access {} from a node object doesn't exist.", accessed_object); + case TError::SERIALIZATION_ERROR: + case TError::VERTEX_HAS_EDGES: + case TError::PROPERTIES_DISABLED: + case TError::VERTEX_ALREADY_INSERTED: + throw ExpressionRuntimeException("Unexpected error when accessing {}.", accessed_object); + case TError::SCHEMA_NO_SCHEMA_DEFINED_FOR_LABEL: + case TError::SCHEMA_VERTEX_PROPERTY_WRONG_TYPE: + case TError::SCHEMA_VERTEX_UPDATE_PRIMARY_KEY: + case TError::SCHEMA_VERTEX_UPDATE_PRIMARY_LABEL: + case TError::SCHEMA_VERTEX_SECONDARY_LABEL_IS_PRIMARY: + case TError::SCHEMA_VERTEX_PRIMARY_PROPERTIES_UNDEFINED: + throw ExpressionRuntimeException("Unexpected schema violation when accessing {}.", accessed_object); + } + } + TypedValue Visit(AndOperator &op) override { auto value1 = op.expression1_->Accept(*this); if (value1.IsBool() && !value1.ValueBool()) { @@ -385,7 +406,7 @@ class ExpressionEvaluator : public ExpressionVisitor { typename TReturnType = std::enable_if_t, bool>> TReturnType HasLabelImpl(const VertexAccessor &vertex, const LabelIx &label, StorageTag /*tag*/) { auto has_label = vertex.HasLabel(view_, GetLabel(label)); - if (has_label.HasError() && has_label.GetError() == Error::NONEXISTENT_OBJECT) { + if (has_label.HasError() && has_label.GetError().code == TError::NONEXISTENT_OBJECT) { // This is a very nasty and temporary hack in order to make MERGE // work. The old storage had the following logic when returning an // `OLD` view: `return old ? old : new`. That means that if the @@ -396,17 +417,7 @@ class ExpressionEvaluator : public ExpressionVisitor { has_label = vertex.HasLabel(StorageView::NEW, GetLabel(label)); } if (has_label.HasError()) { - switch (has_label.GetError()) { - case Error::DELETED_OBJECT: - throw ExpressionRuntimeException("Trying to access labels on a deleted node."); - case Error::NONEXISTENT_OBJECT: - throw ExpressionRuntimeException("Trying to access labels from a node that doesn't exist."); - case Error::SERIALIZATION_ERROR: - case Error::VERTEX_HAS_EDGES: - case Error::PROPERTIES_DISABLED: - case Error::VERTEX_ALREADY_INSERTED: - throw ExpressionRuntimeException("Unexpected error when accessing labels."); - } + HandleShardError(has_label.GetError().code, "labels"); } return *has_label; } @@ -734,7 +745,7 @@ class ExpressionEvaluator : public ExpressionVisitor { class TReturnType = std::enable_if_t, TypedValue>> TypedValue GetProperty(const TRecordAccessor &record_accessor, PropertyIx prop) { auto maybe_prop = record_accessor.GetProperty(view_, ctx_->properties[prop.ix]); - if (maybe_prop.HasError() && maybe_prop.GetError() == Error::NONEXISTENT_OBJECT) { + if (maybe_prop.HasError() && maybe_prop.GetError().code == TError::NONEXISTENT_OBJECT) { // This is a very nasty and temporary hack in order to make MERGE work. // The old storage had the following logic when returning an `OLD` view: // `return old ? old : new`. That means that if the `OLD` view didn't @@ -744,17 +755,7 @@ class ExpressionEvaluator : public ExpressionVisitor { maybe_prop = record_accessor.GetProperty(StorageView::NEW, ctx_->properties[prop.ix]); } if (maybe_prop.HasError()) { - switch (maybe_prop.GetError()) { - case Error::DELETED_OBJECT: - throw ExpressionRuntimeException("Trying to get a property from a deleted object."); - case Error::NONEXISTENT_OBJECT: - throw ExpressionRuntimeException("Trying to get a property from an object that doesn't exist."); - case Error::SERIALIZATION_ERROR: - case Error::VERTEX_HAS_EDGES: - case Error::PROPERTIES_DISABLED: - case Error::VERTEX_ALREADY_INSERTED: - throw ExpressionRuntimeException("Unexpected error when getting a property."); - } + HandleShardError(maybe_prop.GetError().code, "property"); } return conv_(*maybe_prop, ctx_->memory); } @@ -763,7 +764,7 @@ class ExpressionEvaluator : public ExpressionVisitor { class TReturnType = std::enable_if_t, TypedValue>> TypedValue GetProperty(const TRecordAccessor &record_accessor, const std::string_view name) { auto maybe_prop = record_accessor.GetProperty(view_, dba_->NameToProperty(name)); - if (maybe_prop.HasError() && maybe_prop.GetError() == Error::NONEXISTENT_OBJECT) { + if (maybe_prop.HasError() && maybe_prop.GetError().code == TError::NONEXISTENT_OBJECT) { // This is a very nasty and temporary hack in order to make MERGE work. // The old storage had the following logic when returning an `OLD` view: // `return old ? old : new`. That means that if the `OLD` view didn't @@ -773,17 +774,7 @@ class ExpressionEvaluator : public ExpressionVisitor { maybe_prop = record_accessor.GetProperty(view_, dba_->NameToProperty(name)); } if (maybe_prop.HasError()) { - switch (maybe_prop.GetError()) { - case Error::DELETED_OBJECT: - throw ExpressionRuntimeException("Trying to get a property from a deleted object."); - case Error::NONEXISTENT_OBJECT: - throw ExpressionRuntimeException("Trying to get a property from an object that doesn't exist."); - case Error::SERIALIZATION_ERROR: - case Error::VERTEX_HAS_EDGES: - case Error::PROPERTIES_DISABLED: - case Error::VERTEX_ALREADY_INSERTED: - throw ExpressionRuntimeException("Unexpected error when getting a property."); - } + HandleShardError(maybe_prop.GetError().code, "property"); } return conv_(*maybe_prop, ctx_->memory); } diff --git a/src/query/v2/bindings/eval.hpp b/src/query/v2/bindings/eval.hpp index 52455bdb2..78aca436f 100644 --- a/src/query/v2/bindings/eval.hpp +++ b/src/query/v2/bindings/eval.hpp @@ -21,11 +21,12 @@ #include "query/v2/requests.hpp" #include "storage/v3/conversions.hpp" #include "storage/v3/property_value.hpp" +#include "storage/v3/result.hpp" #include "storage/v3/view.hpp" namespace memgraph::msgs { class ShardRequestManagerInterface; -} // namespace memgraph::msgs +} // namespace memgraph::msgs namespace memgraph::query::v2 { @@ -42,8 +43,10 @@ class Callable { }; } // namespace detail -using ExpressionEvaluator = memgraph::expr::ExpressionEvaluator< - TypedValue, memgraph::query::v2::EvaluationContext, memgraph::msgs::ShardRequestManagerInterface, storage::v3::View, - storage::v3::LabelId, msgs::Value, detail::Callable, memgraph::storage::v3::Error, memgraph::expr::QueryEngineTag>; +using ExpressionEvaluator = + memgraph::expr::ExpressionEvaluator; } // namespace memgraph::query::v2 diff --git a/src/storage/v3/bindings/eval.hpp b/src/storage/v3/bindings/eval.hpp index 7f93bb79c..063705806 100644 --- a/src/storage/v3/bindings/eval.hpp +++ b/src/storage/v3/bindings/eval.hpp @@ -21,6 +21,7 @@ #include "storage/v3/id_types.hpp" #include "storage/v3/property_store.hpp" #include "storage/v3/property_value.hpp" +#include "storage/v3/result.hpp" #include "storage/v3/view.hpp" #include "utils/memory.hpp" @@ -87,6 +88,6 @@ struct EvaluationContext { using ExpressionEvaluator = memgraph::expr::ExpressionEvaluator; + memgraph::storage::v3::ErrorCode>; } // namespace memgraph::storage::v3