Adapt mg-expr

This commit is contained in:
jbajic 2022-11-15 18:24:28 +01:00
parent 618237cc96
commit 07032887a4
3 changed files with 37 additions and 42 deletions

View File

@ -32,7 +32,7 @@ struct StorageTag {};
struct QueryEngineTag {}; struct QueryEngineTag {};
template <typename TypedValue, typename EvaluationContext, typename DbAccessor, typename StorageView, typename LabelId, template <typename TypedValue, typename EvaluationContext, typename DbAccessor, typename StorageView, typename LabelId,
typename PropertyValue, typename ConvFunctor, typename Error, typename Tag = StorageTag> typename PropertyValue, typename ConvFunctor, typename TError, typename Tag = StorageTag>
class ExpressionEvaluator : public ExpressionVisitor<TypedValue> { class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
public: public:
ExpressionEvaluator(Frame<TypedValue> *frame, const SymbolTable &symbol_table, const EvaluationContext &ctx, ExpressionEvaluator(Frame<TypedValue> *frame, const SymbolTable &symbol_table, const EvaluationContext &ctx,
@ -100,6 +100,27 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
#undef BINARY_OPERATOR_VISITOR #undef BINARY_OPERATOR_VISITOR
#undef UNARY_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 { TypedValue Visit(AndOperator &op) override {
auto value1 = op.expression1_->Accept(*this); auto value1 = op.expression1_->Accept(*this);
if (value1.IsBool() && !value1.ValueBool()) { if (value1.IsBool() && !value1.ValueBool()) {
@ -385,7 +406,7 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
typename TReturnType = std::enable_if_t<std::is_same_v<TTag, StorageTag>, bool>> typename TReturnType = std::enable_if_t<std::is_same_v<TTag, StorageTag>, bool>>
TReturnType HasLabelImpl(const VertexAccessor &vertex, const LabelIx &label, StorageTag /*tag*/) { TReturnType HasLabelImpl(const VertexAccessor &vertex, const LabelIx &label, StorageTag /*tag*/) {
auto has_label = vertex.HasLabel(view_, GetLabel(label)); 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 // This is a very nasty and temporary hack in order to make MERGE
// work. The old storage had the following logic when returning an // work. The old storage had the following logic when returning an
// `OLD` view: `return old ? old : new`. That means that if the // `OLD` view: `return old ? old : new`. That means that if the
@ -396,17 +417,7 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
has_label = vertex.HasLabel(StorageView::NEW, GetLabel(label)); has_label = vertex.HasLabel(StorageView::NEW, GetLabel(label));
} }
if (has_label.HasError()) { if (has_label.HasError()) {
switch (has_label.GetError()) { HandleShardError(has_label.GetError().code, "labels");
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.");
}
} }
return *has_label; return *has_label;
} }
@ -734,7 +745,7 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
class TReturnType = std::enable_if_t<std::is_same_v<TTag, StorageTag>, TypedValue>> class TReturnType = std::enable_if_t<std::is_same_v<TTag, StorageTag>, TypedValue>>
TypedValue GetProperty(const TRecordAccessor &record_accessor, PropertyIx prop) { TypedValue GetProperty(const TRecordAccessor &record_accessor, PropertyIx prop) {
auto maybe_prop = record_accessor.GetProperty(view_, ctx_->properties[prop.ix]); 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. // 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: // 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 // `return old ? old : new`. That means that if the `OLD` view didn't
@ -744,17 +755,7 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
maybe_prop = record_accessor.GetProperty(StorageView::NEW, ctx_->properties[prop.ix]); maybe_prop = record_accessor.GetProperty(StorageView::NEW, ctx_->properties[prop.ix]);
} }
if (maybe_prop.HasError()) { if (maybe_prop.HasError()) {
switch (maybe_prop.GetError()) { HandleShardError(maybe_prop.GetError().code, "property");
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.");
}
} }
return conv_(*maybe_prop, ctx_->memory); return conv_(*maybe_prop, ctx_->memory);
} }
@ -763,7 +764,7 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
class TReturnType = std::enable_if_t<std::is_same_v<TTag, StorageTag>, TypedValue>> class TReturnType = std::enable_if_t<std::is_same_v<TTag, StorageTag>, TypedValue>>
TypedValue GetProperty(const TRecordAccessor &record_accessor, const std::string_view name) { TypedValue GetProperty(const TRecordAccessor &record_accessor, const std::string_view name) {
auto maybe_prop = record_accessor.GetProperty(view_, dba_->NameToProperty(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. // 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: // 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 // `return old ? old : new`. That means that if the `OLD` view didn't
@ -773,17 +774,7 @@ class ExpressionEvaluator : public ExpressionVisitor<TypedValue> {
maybe_prop = record_accessor.GetProperty(view_, dba_->NameToProperty(name)); maybe_prop = record_accessor.GetProperty(view_, dba_->NameToProperty(name));
} }
if (maybe_prop.HasError()) { if (maybe_prop.HasError()) {
switch (maybe_prop.GetError()) { HandleShardError(maybe_prop.GetError().code, "property");
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.");
}
} }
return conv_(*maybe_prop, ctx_->memory); return conv_(*maybe_prop, ctx_->memory);
} }

View File

@ -21,11 +21,12 @@
#include "query/v2/requests.hpp" #include "query/v2/requests.hpp"
#include "storage/v3/conversions.hpp" #include "storage/v3/conversions.hpp"
#include "storage/v3/property_value.hpp" #include "storage/v3/property_value.hpp"
#include "storage/v3/result.hpp"
#include "storage/v3/view.hpp" #include "storage/v3/view.hpp"
namespace memgraph::msgs { namespace memgraph::msgs {
class ShardRequestManagerInterface; class ShardRequestManagerInterface;
} // namespace memgraph::msgs } // namespace memgraph::msgs
namespace memgraph::query::v2 { namespace memgraph::query::v2 {
@ -42,8 +43,10 @@ class Callable {
}; };
} // namespace detail } // namespace detail
using ExpressionEvaluator = memgraph::expr::ExpressionEvaluator< using ExpressionEvaluator =
TypedValue, memgraph::query::v2::EvaluationContext, memgraph::msgs::ShardRequestManagerInterface, storage::v3::View, memgraph::expr::ExpressionEvaluator<TypedValue, memgraph::query::v2::EvaluationContext,
storage::v3::LabelId, msgs::Value, detail::Callable, memgraph::storage::v3::Error, memgraph::expr::QueryEngineTag>; memgraph::msgs::ShardRequestManagerInterface, storage::v3::View,
storage::v3::LabelId, msgs::Value, detail::Callable,
memgraph::storage::v3::ErrorCode, memgraph::expr::QueryEngineTag>;
} // namespace memgraph::query::v2 } // namespace memgraph::query::v2

View File

@ -21,6 +21,7 @@
#include "storage/v3/id_types.hpp" #include "storage/v3/id_types.hpp"
#include "storage/v3/property_store.hpp" #include "storage/v3/property_store.hpp"
#include "storage/v3/property_value.hpp" #include "storage/v3/property_value.hpp"
#include "storage/v3/result.hpp"
#include "storage/v3/view.hpp" #include "storage/v3/view.hpp"
#include "utils/memory.hpp" #include "utils/memory.hpp"
@ -87,6 +88,6 @@ struct EvaluationContext {
using ExpressionEvaluator = using ExpressionEvaluator =
memgraph::expr::ExpressionEvaluator<TypedValue, EvaluationContext, DbAccessor, storage::v3::View, memgraph::expr::ExpressionEvaluator<TypedValue, EvaluationContext, DbAccessor, storage::v3::View,
storage::v3::LabelId, storage::v3::PropertyStore, PropertyToTypedValueConverter, storage::v3::LabelId, storage::v3::PropertyStore, PropertyToTypedValueConverter,
memgraph::storage::v3::Error>; memgraph::storage::v3::ErrorCode>;
} // namespace memgraph::storage::v3 } // namespace memgraph::storage::v3