Remove MG_SINGLE_NODE_V2 define
Reviewers: teon.banek Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D2637
This commit is contained in:
parent
6d10d90d98
commit
0683ed4134
@ -161,7 +161,6 @@ endif()
|
||||
# memgraph main executable
|
||||
add_executable(memgraph ${mg_single_node_v2_sources})
|
||||
target_include_directories(memgraph PUBLIC ${CMAKE_SOURCE_DIR}/include)
|
||||
target_compile_definitions(memgraph PUBLIC MG_SINGLE_NODE_V2)
|
||||
target_link_libraries(memgraph ${MG_SINGLE_NODE_V2_LIBS})
|
||||
# NOTE: `include/mg_procedure.syms` describes a pattern match for symbols which
|
||||
# should be dynamically exported, so that `dlopen` can correctly link the
|
||||
|
@ -4,13 +4,9 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
#include "storage/v2/edge_accessor.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
#include "storage/v2/vertex_accessor.hpp"
|
||||
#else
|
||||
#include "database/graph_db_accessor.hpp"
|
||||
#endif
|
||||
|
||||
using communication::bolt::Value;
|
||||
|
||||
@ -49,7 +45,6 @@ query::TypedValue ToTypedValue(const Value &value) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
storage::Result<communication::bolt::Vertex> ToBoltVertex(
|
||||
const query::VertexAccessor &vertex, const storage::Storage &db,
|
||||
storage::View view) {
|
||||
@ -61,25 +56,10 @@ storage::Result<communication::bolt::Edge> ToBoltEdge(
|
||||
storage::View view) {
|
||||
return ToBoltEdge(edge.impl_, db, view);
|
||||
}
|
||||
#else
|
||||
communication::bolt::Vertex ToBoltVertex(const query::VertexAccessor &vertex,
|
||||
storage::View view) {
|
||||
return ToBoltVertex(vertex.impl_, view);
|
||||
}
|
||||
|
||||
communication::bolt::Edge ToBoltEdge(const query::EdgeAccessor &edge,
|
||||
storage::View view) {
|
||||
return ToBoltEdge(edge.impl_, view);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
storage::Result<Value> ToBoltValue(const query::TypedValue &value,
|
||||
const storage::Storage &db,
|
||||
storage::View view) {
|
||||
#else
|
||||
Value ToBoltValue(const query::TypedValue &value, storage::View view) {
|
||||
#endif
|
||||
switch (value.type()) {
|
||||
case query::TypedValue::Type::Null:
|
||||
return Value();
|
||||
@ -95,63 +75,42 @@ Value ToBoltValue(const query::TypedValue &value, storage::View view) {
|
||||
std::vector<Value> values;
|
||||
values.reserve(value.ValueList().size());
|
||||
for (const auto &v : value.ValueList()) {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
auto maybe_value = ToBoltValue(v, db, view);
|
||||
if (maybe_value.HasError()) return maybe_value.GetError();
|
||||
values.emplace_back(std::move(*maybe_value));
|
||||
#else
|
||||
values.push_back(ToBoltValue(v, view));
|
||||
#endif
|
||||
}
|
||||
return Value(std::move(values));
|
||||
}
|
||||
case query::TypedValue::Type::Map: {
|
||||
std::map<std::string, Value> map;
|
||||
for (const auto &kv : value.ValueMap()) {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
auto maybe_value = ToBoltValue(kv.second, db, view);
|
||||
if (maybe_value.HasError()) return maybe_value.GetError();
|
||||
map.emplace(kv.first, std::move(*maybe_value));
|
||||
#else
|
||||
map.emplace(kv.first, ToBoltValue(kv.second, view));
|
||||
#endif
|
||||
}
|
||||
return Value(std::move(map));
|
||||
}
|
||||
case query::TypedValue::Type::Vertex:
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
{
|
||||
auto maybe_vertex = ToBoltVertex(value.ValueVertex(), db, view);
|
||||
if (maybe_vertex.HasError()) return maybe_vertex.GetError();
|
||||
return Value(std::move(*maybe_vertex));
|
||||
}
|
||||
#else
|
||||
return Value(ToBoltVertex(value.ValueVertex(), view));
|
||||
#endif
|
||||
case query::TypedValue::Type::Edge:
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
{
|
||||
auto maybe_edge = ToBoltEdge(value.ValueEdge(), db, view);
|
||||
if (maybe_edge.HasError()) return maybe_edge.GetError();
|
||||
return Value(std::move(*maybe_edge));
|
||||
}
|
||||
#else
|
||||
return Value(ToBoltEdge(value.ValueEdge(), view));
|
||||
#endif
|
||||
case query::TypedValue::Type::Path:
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
{
|
||||
auto maybe_path = ToBoltPath(value.ValuePath(), db, view);
|
||||
if (maybe_path.HasError()) return maybe_path.GetError();
|
||||
return Value(std::move(*maybe_path));
|
||||
}
|
||||
#else
|
||||
return Value(ToBoltPath(value.ValuePath(), view));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
storage::Result<communication::bolt::Vertex> ToBoltVertex(
|
||||
const storage::VertexAccessor &vertex, const storage::Storage &db,
|
||||
storage::View view) {
|
||||
@ -188,85 +147,22 @@ storage::Result<communication::bolt::Edge> ToBoltEdge(
|
||||
}
|
||||
return communication::bolt::Edge{id, from, to, type, properties};
|
||||
}
|
||||
#else
|
||||
communication::bolt::Vertex ToBoltVertex(const ::VertexAccessor &vertex,
|
||||
storage::View view) {
|
||||
// NOTE: This hack will be removed when we switch to storage v2 API.
|
||||
switch (view) {
|
||||
case storage::View::OLD:
|
||||
const_cast<::VertexAccessor &>(vertex).SwitchOld();
|
||||
break;
|
||||
case storage::View::NEW:
|
||||
const_cast<::VertexAccessor &>(vertex).SwitchNew();
|
||||
break;
|
||||
}
|
||||
auto id = communication::bolt::Id::FromUint(vertex.gid().AsUint());
|
||||
std::vector<std::string> labels;
|
||||
labels.reserve(vertex.labels().size());
|
||||
for (const auto &label : vertex.labels()) {
|
||||
labels.push_back(vertex.db_accessor().LabelName(label));
|
||||
}
|
||||
std::map<std::string, Value> properties;
|
||||
for (const auto &prop : vertex.Properties()) {
|
||||
properties[vertex.db_accessor().PropertyName(prop.first)] =
|
||||
ToBoltValue(prop.second);
|
||||
}
|
||||
return communication::bolt::Vertex{id, std::move(labels),
|
||||
std::move(properties)};
|
||||
}
|
||||
|
||||
communication::bolt::Edge ToBoltEdge(const ::EdgeAccessor &edge,
|
||||
storage::View view) {
|
||||
// NOTE: This hack will be removed when we switch to storage v2 API.
|
||||
switch (view) {
|
||||
case storage::View::OLD:
|
||||
const_cast<::EdgeAccessor &>(edge).SwitchOld();
|
||||
break;
|
||||
case storage::View::NEW:
|
||||
const_cast<::EdgeAccessor &>(edge).SwitchNew();
|
||||
break;
|
||||
}
|
||||
auto id = communication::bolt::Id::FromUint(edge.gid().AsUint());
|
||||
auto from = communication::bolt::Id::FromUint(edge.from().gid().AsUint());
|
||||
auto to = communication::bolt::Id::FromUint(edge.to().gid().AsUint());
|
||||
auto type = edge.db_accessor().EdgeTypeName(edge.EdgeType());
|
||||
std::map<std::string, Value> properties;
|
||||
for (const auto &prop : edge.Properties()) {
|
||||
properties[edge.db_accessor().PropertyName(prop.first)] =
|
||||
ToBoltValue(prop.second);
|
||||
}
|
||||
return communication::bolt::Edge{id, from, to, type, std::move(properties)};
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
storage::Result<communication::bolt::Path> ToBoltPath(
|
||||
const query::Path &path, const storage::Storage &db, storage::View view) {
|
||||
#else
|
||||
communication::bolt::Path ToBoltPath(const query::Path &path,
|
||||
storage::View view) {
|
||||
#endif
|
||||
std::vector<communication::bolt::Vertex> vertices;
|
||||
vertices.reserve(path.vertices().size());
|
||||
for (const auto &v : path.vertices()) {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
auto maybe_vertex = ToBoltVertex(v, db, view);
|
||||
if (maybe_vertex.HasError()) return maybe_vertex.GetError();
|
||||
vertices.emplace_back(std::move(*maybe_vertex));
|
||||
#else
|
||||
vertices.push_back(ToBoltVertex(v, view));
|
||||
#endif
|
||||
}
|
||||
std::vector<communication::bolt::Edge> edges;
|
||||
edges.reserve(path.edges().size());
|
||||
for (const auto &e : path.edges()) {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
auto maybe_edge = ToBoltEdge(e, db, view);
|
||||
if (maybe_edge.HasError()) return maybe_edge.GetError();
|
||||
edges.emplace_back(std::move(*maybe_edge));
|
||||
#else
|
||||
edges.push_back(ToBoltEdge(e, view));
|
||||
#endif
|
||||
}
|
||||
return communication::bolt::Path(vertices, edges);
|
||||
}
|
||||
|
@ -4,21 +4,17 @@
|
||||
#include "communication/bolt/v1/value.hpp"
|
||||
#include "query/typed_value.hpp"
|
||||
#include "storage/v2/property_value.hpp"
|
||||
#include "storage/v2/view.hpp"
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
#include "storage/v2/result.hpp"
|
||||
#include "storage/v2/view.hpp"
|
||||
|
||||
namespace storage {
|
||||
class EdgeAccessor;
|
||||
class Storage;
|
||||
class VertexAccessor;
|
||||
} // namespace storage
|
||||
#endif
|
||||
|
||||
namespace glue {
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
/// @param storage::VertexAccessor for converting to
|
||||
/// communication::bolt::Vertex.
|
||||
/// @param storage::Storage for getting label and property names.
|
||||
@ -54,19 +50,6 @@ storage::Result<communication::bolt::Path> ToBoltPath(
|
||||
storage::Result<communication::bolt::Value> ToBoltValue(
|
||||
const query::TypedValue &value, const storage::Storage &db,
|
||||
storage::View view);
|
||||
#else
|
||||
communication::bolt::Vertex ToBoltVertex(const ::VertexAccessor &vertex,
|
||||
storage::View view);
|
||||
|
||||
communication::bolt::Edge ToBoltEdge(const ::EdgeAccessor &edge,
|
||||
storage::View view);
|
||||
|
||||
communication::bolt::Path ToBoltPath(const query::Path &path,
|
||||
storage::View view);
|
||||
|
||||
communication::bolt::Value ToBoltValue(const query::TypedValue &value,
|
||||
storage::View view);
|
||||
#endif
|
||||
|
||||
query::TypedValue ToTypedValue(const communication::bolt::Value &value);
|
||||
|
||||
|
@ -10,11 +10,7 @@
|
||||
#include <glog/logging.h>
|
||||
|
||||
#include "communication/server.hpp"
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
#include "storage/v2/storage.hpp"
|
||||
#else
|
||||
#include "database/single_node/graph_db.hpp"
|
||||
#endif
|
||||
#include "glue/auth.hpp"
|
||||
#include "memgraph_init.hpp"
|
||||
#include "query/exceptions.hpp"
|
||||
@ -45,7 +41,6 @@ DEFINE_string(bolt_cert_file, "",
|
||||
DEFINE_string(bolt_key_file, "",
|
||||
"Key file which should be used for the Bolt server.");
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
// General purpose flags.
|
||||
DEFINE_string(data_directory, "mg_data",
|
||||
"Path to directory in which to save all permanent data.");
|
||||
@ -80,7 +75,6 @@ DEFINE_VALIDATED_uint64(
|
||||
FLAG_IN_RANGE(1, 1000000));
|
||||
DEFINE_bool(storage_snapshot_on_exit, false,
|
||||
"Controls whether the storage creates another snapshot on exit.");
|
||||
#endif
|
||||
|
||||
DEFINE_bool(telemetry_enabled, false,
|
||||
"Set to true to enable telemetry. We collect information about the "
|
||||
@ -437,11 +431,7 @@ void SingleNodeMain() {
|
||||
|
||||
// Begin enterprise features initialization
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
auto data_directory = std::filesystem::path(FLAGS_data_directory);
|
||||
#else
|
||||
auto data_directory = std::filesystem::path(FLAGS_durability_directory);
|
||||
#endif
|
||||
|
||||
// Auth
|
||||
auth::Auth auth{data_directory / "auth"};
|
||||
@ -463,7 +453,6 @@ void SingleNodeMain() {
|
||||
|
||||
// Main storage and execution engines initialization
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
storage::Config db_config{
|
||||
.gc = {.type = storage::Config::Gc::Type::PERIODIC,
|
||||
.interval = std::chrono::seconds(FLAGS_storage_gc_cycle_sec)},
|
||||
@ -494,9 +483,6 @@ void SingleNodeMain() {
|
||||
std::chrono::seconds(FLAGS_storage_snapshot_interval_sec);
|
||||
}
|
||||
storage::Storage db(db_config);
|
||||
#else
|
||||
database::GraphDb db;
|
||||
#endif
|
||||
query::InterpreterContext interpreter_context{&db};
|
||||
query::SetExecutionTimeout(&interpreter_context,
|
||||
FLAGS_query_execution_timeout_sec);
|
||||
@ -531,17 +517,10 @@ void SingleNodeMain() {
|
||||
telemetry.emplace(
|
||||
"https://telemetry.memgraph.com/88b5e7e8-746a-11e8-9f85-538a9e9690cc/",
|
||||
data_directory / "telemetry", std::chrono::minutes(10));
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
telemetry->AddCollector("db", [&db]() -> nlohmann::json {
|
||||
auto info = db.GetInfo();
|
||||
return {{"vertices", info.vertex_count}, {"edges", info.edge_count}};
|
||||
});
|
||||
#else
|
||||
telemetry->AddCollector("db", [&db]() -> nlohmann::json {
|
||||
auto dba = db.Access();
|
||||
return {{"vertices", dba.VerticesCount()}, {"edges", dba.EdgesCount()}};
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
// Handler for regular termination signals
|
||||
|
@ -32,9 +32,7 @@ BoltSession::BoltSession(SessionData *data,
|
||||
: communication::bolt::Session<communication::InputStream,
|
||||
communication::OutputStream>(input_stream,
|
||||
output_stream),
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
db_(data->db),
|
||||
#endif
|
||||
interpreter_(data->interpreter_context),
|
||||
#ifndef MG_SINGLE_NODE_HA
|
||||
auth_(data->auth),
|
||||
@ -85,15 +83,10 @@ std::vector<std::string> BoltSession::Interpret(
|
||||
std::map<std::string, communication::bolt::Value> BoltSession::PullAll(
|
||||
TEncoder *encoder) {
|
||||
try {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
TypedValueResultStream stream(encoder, db_);
|
||||
#else
|
||||
TypedValueResultStream stream(encoder);
|
||||
#endif
|
||||
const auto &summary = interpreter_.PullAll(&stream);
|
||||
std::map<std::string, communication::bolt::Value> decoded_summary;
|
||||
for (const auto &kv : summary) {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
auto maybe_value = glue::ToBoltValue(kv.second, *db_, storage::View::NEW);
|
||||
if (maybe_value.HasError()) {
|
||||
switch (maybe_value.GetError()) {
|
||||
@ -107,10 +100,6 @@ std::map<std::string, communication::bolt::Value> BoltSession::PullAll(
|
||||
}
|
||||
}
|
||||
decoded_summary.emplace(kv.first, std::move(*maybe_value));
|
||||
#else
|
||||
decoded_summary.emplace(kv.first,
|
||||
glue::ToBoltValue(kv.second, storage::View::NEW));
|
||||
#endif
|
||||
}
|
||||
return decoded_summary;
|
||||
} catch (const query::QueryException &e) {
|
||||
@ -138,21 +127,15 @@ std::optional<std::string> BoltSession::GetServerNameForInit() {
|
||||
return FLAGS_bolt_server_name_for_init;
|
||||
}
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
BoltSession::TypedValueResultStream::TypedValueResultStream(
|
||||
TEncoder *encoder, const storage::Storage *db)
|
||||
: encoder_(encoder), db_(db) {}
|
||||
#else
|
||||
BoltSession::TypedValueResultStream::TypedValueResultStream(TEncoder *encoder)
|
||||
: encoder_(encoder) {}
|
||||
#endif
|
||||
|
||||
void BoltSession::TypedValueResultStream::Result(
|
||||
const std::vector<query::TypedValue> &values) {
|
||||
std::vector<communication::bolt::Value> decoded_values;
|
||||
decoded_values.reserve(values.size());
|
||||
for (const auto &v : values) {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
auto maybe_value = glue::ToBoltValue(v, *db_, storage::View::NEW);
|
||||
if (maybe_value.HasError()) {
|
||||
switch (maybe_value.GetError()) {
|
||||
@ -170,9 +153,6 @@ void BoltSession::TypedValueResultStream::Result(
|
||||
}
|
||||
}
|
||||
decoded_values.emplace_back(std::move(*maybe_value));
|
||||
#else
|
||||
decoded_values.push_back(glue::ToBoltValue(v, storage::View::NEW));
|
||||
#endif
|
||||
}
|
||||
encoder_->MessageRecord(decoded_values);
|
||||
}
|
||||
|
@ -17,27 +17,19 @@
|
||||
#include "communication/session.hpp"
|
||||
#include "query/interpreter.hpp"
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
namespace database {
|
||||
using GraphDb = storage::Storage;
|
||||
}
|
||||
#endif
|
||||
|
||||
DECLARE_string(durability_directory);
|
||||
|
||||
/// Encapsulates Dbms and Interpreter that are passed through the network server
|
||||
/// and worker to the session.
|
||||
struct SessionData {
|
||||
// Explicit constructor here to ensure that pointers to all objects are
|
||||
// supplied.
|
||||
SessionData(database::GraphDb *_db,
|
||||
SessionData(storage::Storage *_db,
|
||||
query::InterpreterContext *_interpreter_context,
|
||||
auth::Auth *_auth, audit::Log *_audit_log)
|
||||
: db(_db),
|
||||
interpreter_context(_interpreter_context),
|
||||
auth(_auth),
|
||||
audit_log(_audit_log) {}
|
||||
database::GraphDb *db;
|
||||
storage::Storage *db;
|
||||
query::InterpreterContext *interpreter_context;
|
||||
auth::Auth *auth;
|
||||
audit::Log *audit_log;
|
||||
@ -73,26 +65,18 @@ class BoltSession final
|
||||
/// before forwarding the calls to original TEncoder.
|
||||
class TypedValueResultStream {
|
||||
public:
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
TypedValueResultStream(TEncoder *encoder, const storage::Storage *db);
|
||||
#else
|
||||
TypedValueResultStream(TEncoder *encoder);
|
||||
#endif
|
||||
|
||||
void Result(const std::vector<query::TypedValue> &values);
|
||||
|
||||
private:
|
||||
TEncoder *encoder_;
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
// NOTE: Needed only for ToBoltValue conversions
|
||||
const storage::Storage *db_;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
// NOTE: Needed only for ToBoltValue conversions
|
||||
const storage::Storage *db_;
|
||||
#endif
|
||||
query::Interpreter interpreter_;
|
||||
#ifndef MG_SINGLE_NODE_HA
|
||||
auth::Auth *auth_;
|
||||
|
@ -32,7 +32,6 @@ set(mg_query_sources
|
||||
add_library(mg-query STATIC ${mg_query_sources})
|
||||
add_dependencies(mg-query generate_lcp_query)
|
||||
add_dependencies(mg-query generate_opencypher_parser)
|
||||
target_compile_definitions(mg-query PUBLIC MG_SINGLE_NODE_V2)
|
||||
target_include_directories(mg-query PRIVATE ${CMAKE_SOURCE_DIR}/include)
|
||||
target_link_libraries(mg-query dl cppitertools antlr_opencypher_parser_lib)
|
||||
target_link_libraries(mg-query mg-storage-v2)
|
||||
|
@ -6,26 +6,18 @@
|
||||
#include <cppitertools/imap.hpp>
|
||||
|
||||
#include "query/exceptions.hpp"
|
||||
#include "storage/edge_accessor.hpp"
|
||||
#include "storage/v2/id_types.hpp"
|
||||
#include "storage/v2/property_value.hpp"
|
||||
#include "storage/v2/result.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
#include "storage/v2/view.hpp"
|
||||
#include "storage/vertex_accessor.hpp"
|
||||
#include "utils/bound.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
#include "storage/v2/storage.hpp"
|
||||
#else
|
||||
#include "database/graph_db_accessor.hpp"
|
||||
#endif
|
||||
|
||||
namespace query {
|
||||
|
||||
class VertexAccessor;
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
class EdgeAccessor final {
|
||||
public:
|
||||
storage::EdgeAccessor impl_;
|
||||
@ -189,294 +181,7 @@ inline VertexAccessor EdgeAccessor::From() const {
|
||||
}
|
||||
|
||||
inline bool EdgeAccessor::IsCycle() const { return To() == From(); }
|
||||
#else
|
||||
|
||||
class EdgeAccessor final {
|
||||
public:
|
||||
::EdgeAccessor impl_;
|
||||
|
||||
private:
|
||||
void SwitchToView(storage::View view) const {
|
||||
if (!const_cast<::EdgeAccessor &>(impl_).Reconstruct())
|
||||
throw ReconstructionException();
|
||||
switch (view) {
|
||||
case storage::View::OLD:
|
||||
const_cast<::EdgeAccessor &>(impl_).SwitchOld();
|
||||
break;
|
||||
case storage::View::NEW:
|
||||
const_cast<::EdgeAccessor &>(impl_).SwitchNew();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
explicit EdgeAccessor(::EdgeAccessor impl) : impl_(impl) {}
|
||||
|
||||
storage::EdgeType EdgeType() const { return impl_.EdgeType(); }
|
||||
|
||||
storage::Result<PropertyValueStore> Properties(storage::View view) const {
|
||||
SwitchToView(view);
|
||||
return impl_.Properties();
|
||||
}
|
||||
|
||||
storage::Result<PropertyValue> GetProperty(storage::View view,
|
||||
storage::Property key) const {
|
||||
SwitchToView(view);
|
||||
return impl_.PropsAt(key);
|
||||
}
|
||||
|
||||
storage::Result<bool> SetProperty(storage::Property key,
|
||||
const PropertyValue &value) {
|
||||
SwitchToView(storage::View::NEW);
|
||||
try {
|
||||
impl_.PropsSet(key, value);
|
||||
return true;
|
||||
} catch (const RecordDeletedError &) {
|
||||
return storage::Error::DELETED_OBJECT;
|
||||
} catch (const mvcc::SerializationError &) {
|
||||
return storage::Error::SERIALIZATION_ERROR;
|
||||
} catch (const database::ConstraintViolationException &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
storage::Result<bool> RemoveProperty(storage::Property key) {
|
||||
SwitchToView(storage::View::NEW);
|
||||
try {
|
||||
impl_.PropsErase(key);
|
||||
return true;
|
||||
} catch (const RecordDeletedError &) {
|
||||
return storage::Error::DELETED_OBJECT;
|
||||
} catch (const mvcc::SerializationError &) {
|
||||
return storage::Error::SERIALIZATION_ERROR;
|
||||
} catch (const database::ConstraintViolationException &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
utils::BasicResult<storage::Error, void> ClearProperties() {
|
||||
SwitchToView(storage::View::NEW);
|
||||
try {
|
||||
impl_.PropsClear();
|
||||
return {};
|
||||
} catch (const RecordDeletedError &) {
|
||||
return storage::Error::DELETED_OBJECT;
|
||||
} catch (const mvcc::SerializationError &) {
|
||||
return storage::Error::SERIALIZATION_ERROR;
|
||||
} catch (const database::ConstraintViolationException &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
VertexAccessor To() const;
|
||||
|
||||
VertexAccessor From() const;
|
||||
|
||||
bool IsCycle() const;
|
||||
|
||||
int64_t CypherId() const { return impl_.CypherId(); }
|
||||
|
||||
auto Gid() const { return impl_.gid(); }
|
||||
|
||||
bool operator==(const EdgeAccessor &e) const { return impl_ == e.impl_; }
|
||||
|
||||
bool operator!=(const EdgeAccessor &e) const { return !(*this == e); }
|
||||
};
|
||||
|
||||
class VertexAccessor final {
|
||||
public:
|
||||
::VertexAccessor impl_;
|
||||
|
||||
private:
|
||||
void SwitchToView(storage::View view) const {
|
||||
if (!const_cast<::VertexAccessor &>(impl_).Reconstruct())
|
||||
throw ReconstructionException();
|
||||
switch (view) {
|
||||
case storage::View::OLD:
|
||||
const_cast<::VertexAccessor &>(impl_).SwitchOld();
|
||||
break;
|
||||
case storage::View::NEW:
|
||||
const_cast<::VertexAccessor &>(impl_).SwitchNew();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static EdgeAccessor MakeEdgeAccessor(const ::EdgeAccessor impl) {
|
||||
return EdgeAccessor(impl);
|
||||
}
|
||||
|
||||
public:
|
||||
explicit VertexAccessor(::VertexAccessor impl) : impl_(impl) {}
|
||||
|
||||
storage::Result<std::vector<storage::Label>> Labels(
|
||||
storage::View view) const {
|
||||
SwitchToView(view);
|
||||
return impl_.labels();
|
||||
}
|
||||
|
||||
storage::Result<bool> AddLabel(storage::Label label) {
|
||||
SwitchToView(storage::View::NEW);
|
||||
try {
|
||||
impl_.add_label(label);
|
||||
return true;
|
||||
} catch (const RecordDeletedError &) {
|
||||
return storage::Error::DELETED_OBJECT;
|
||||
} catch (const mvcc::SerializationError &) {
|
||||
return storage::Error::SERIALIZATION_ERROR;
|
||||
} catch (const database::ConstraintViolationException &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
storage::Result<bool> RemoveLabel(storage::Label label) {
|
||||
SwitchToView(storage::View::NEW);
|
||||
try {
|
||||
impl_.remove_label(label);
|
||||
return true;
|
||||
} catch (const RecordDeletedError &) {
|
||||
return storage::Error::DELETED_OBJECT;
|
||||
} catch (const mvcc::SerializationError &) {
|
||||
return storage::Error::SERIALIZATION_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
storage::Result<bool> HasLabel(storage::View view,
|
||||
storage::Label label) const {
|
||||
SwitchToView(view);
|
||||
return impl_.has_label(label);
|
||||
}
|
||||
|
||||
storage::Result<PropertyValueStore> Properties(storage::View view) const {
|
||||
SwitchToView(view);
|
||||
return impl_.Properties();
|
||||
}
|
||||
|
||||
storage::Result<PropertyValue> GetProperty(storage::View view,
|
||||
storage::Property key) const {
|
||||
SwitchToView(view);
|
||||
return impl_.PropsAt(key);
|
||||
}
|
||||
|
||||
storage::Result<bool> SetProperty(storage::Property key,
|
||||
const PropertyValue &value) {
|
||||
SwitchToView(storage::View::NEW);
|
||||
try {
|
||||
impl_.PropsSet(key, value);
|
||||
return true;
|
||||
} catch (const RecordDeletedError &) {
|
||||
return storage::Error::DELETED_OBJECT;
|
||||
} catch (const mvcc::SerializationError &) {
|
||||
return storage::Error::SERIALIZATION_ERROR;
|
||||
} catch (const database::ConstraintViolationException &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
storage::Result<bool> RemoveProperty(storage::Property key) {
|
||||
SwitchToView(storage::View::NEW);
|
||||
try {
|
||||
impl_.PropsErase(key);
|
||||
return true;
|
||||
} catch (const RecordDeletedError &) {
|
||||
return storage::Error::DELETED_OBJECT;
|
||||
} catch (const mvcc::SerializationError &) {
|
||||
return storage::Error::SERIALIZATION_ERROR;
|
||||
} catch (const database::ConstraintViolationException &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
utils::BasicResult<storage::Error, void> ClearProperties() {
|
||||
SwitchToView(storage::View::NEW);
|
||||
try {
|
||||
impl_.PropsClear();
|
||||
return {};
|
||||
} catch (const RecordDeletedError &) {
|
||||
return storage::Error::DELETED_OBJECT;
|
||||
} catch (const mvcc::SerializationError &) {
|
||||
return storage::Error::SERIALIZATION_ERROR;
|
||||
} catch (const database::ConstraintViolationException &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
}
|
||||
}
|
||||
|
||||
auto InEdges(storage::View view) const
|
||||
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor, impl_.in()))> {
|
||||
SwitchToView(view);
|
||||
return iter::imap(MakeEdgeAccessor, impl_.in());
|
||||
}
|
||||
|
||||
auto InEdges(storage::View view,
|
||||
const std::vector<storage::EdgeType> &edge_types) const
|
||||
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor,
|
||||
impl_.in(&edge_types)))> {
|
||||
SwitchToView(view);
|
||||
return iter::imap(MakeEdgeAccessor, impl_.in(&edge_types));
|
||||
}
|
||||
|
||||
auto InEdges(storage::View view,
|
||||
const std::vector<storage::EdgeType> &edge_types,
|
||||
const VertexAccessor &dest) const
|
||||
-> storage::Result<decltype(
|
||||
iter::imap(MakeEdgeAccessor, impl_.in(dest.impl_, &edge_types)))> {
|
||||
SwitchToView(view);
|
||||
return iter::imap(MakeEdgeAccessor, impl_.in(dest.impl_, &edge_types));
|
||||
}
|
||||
|
||||
auto OutEdges(storage::View view) const
|
||||
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor, impl_.out()))> {
|
||||
SwitchToView(view);
|
||||
return iter::imap(MakeEdgeAccessor, impl_.out());
|
||||
}
|
||||
|
||||
auto OutEdges(storage::View view,
|
||||
const std::vector<storage::EdgeType> &edge_types) const
|
||||
-> storage::Result<decltype(iter::imap(MakeEdgeAccessor,
|
||||
impl_.out(&edge_types)))> {
|
||||
SwitchToView(view);
|
||||
return iter::imap(MakeEdgeAccessor, impl_.out(&edge_types));
|
||||
}
|
||||
|
||||
auto OutEdges(storage::View view,
|
||||
const std::vector<storage::EdgeType> &edge_types,
|
||||
const VertexAccessor &dest) const
|
||||
-> storage::Result<decltype(
|
||||
iter::imap(MakeEdgeAccessor, impl_.out(dest.impl_, &edge_types)))> {
|
||||
SwitchToView(view);
|
||||
return iter::imap(MakeEdgeAccessor, impl_.out(dest.impl_, &edge_types));
|
||||
}
|
||||
|
||||
storage::Result<size_t> InDegree(storage::View view) const {
|
||||
SwitchToView(view);
|
||||
return impl_.in_degree();
|
||||
}
|
||||
|
||||
storage::Result<size_t> OutDegree(storage::View view) const {
|
||||
SwitchToView(view);
|
||||
return impl_.out_degree();
|
||||
}
|
||||
|
||||
int64_t CypherId() const { return impl_.CypherId(); }
|
||||
|
||||
auto Gid() const { return impl_.gid(); }
|
||||
|
||||
bool operator==(const VertexAccessor &v) const { return impl_ == v.impl_; }
|
||||
|
||||
bool operator!=(const VertexAccessor &v) const { return !(*this == v); }
|
||||
};
|
||||
|
||||
inline VertexAccessor EdgeAccessor::To() const {
|
||||
return VertexAccessor(impl_.to());
|
||||
}
|
||||
|
||||
inline VertexAccessor EdgeAccessor::From() const {
|
||||
return VertexAccessor(impl_.from());
|
||||
}
|
||||
|
||||
inline bool EdgeAccessor::IsCycle() const { return To() == From(); }
|
||||
#endif
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
class DbAccessor final {
|
||||
storage::Storage::Accessor *accessor_;
|
||||
|
||||
@ -643,226 +348,6 @@ class DbAccessor final {
|
||||
return accessor_->ListAllConstraints();
|
||||
}
|
||||
};
|
||||
#else
|
||||
class DbAccessor final {
|
||||
database::GraphDbAccessor *dba_;
|
||||
|
||||
template <class TVertices>
|
||||
class VerticesIterable final {
|
||||
TVertices vertices_;
|
||||
|
||||
class Iterator final {
|
||||
decltype(vertices_.begin()) it_;
|
||||
|
||||
public:
|
||||
explicit Iterator(decltype(it_) it) : it_(std::move(it)) {}
|
||||
|
||||
VertexAccessor operator*() { return VertexAccessor(*it_); }
|
||||
|
||||
Iterator &operator++() {
|
||||
++it_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Iterator &other) const { return other.it_ == it_; }
|
||||
|
||||
bool operator!=(const Iterator &other) const { return !(other == *this); }
|
||||
};
|
||||
|
||||
public:
|
||||
explicit VerticesIterable(TVertices vertices)
|
||||
: vertices_(std::move(vertices)) {}
|
||||
|
||||
Iterator begin() { return Iterator(vertices_.begin()); }
|
||||
|
||||
Iterator end() { return Iterator(vertices_.end()); }
|
||||
};
|
||||
|
||||
public:
|
||||
explicit DbAccessor(database::GraphDbAccessor *dba) : dba_(dba) {}
|
||||
|
||||
VertexAccessor InsertVertex() { return VertexAccessor(dba_->InsertVertex()); }
|
||||
|
||||
storage::Result<EdgeAccessor> InsertEdge(VertexAccessor *from,
|
||||
VertexAccessor *to,
|
||||
const storage::EdgeType &edge_type) {
|
||||
try {
|
||||
return EdgeAccessor(dba_->InsertEdge(from->impl_, to->impl_, edge_type));
|
||||
} catch (const mvcc::SerializationError &) {
|
||||
return storage::Error::SERIALIZATION_ERROR;
|
||||
} catch (const RecordDeletedError &) {
|
||||
return storage::Error::DELETED_OBJECT;
|
||||
}
|
||||
}
|
||||
|
||||
storage::Result<bool> RemoveEdge(EdgeAccessor *edge) {
|
||||
try {
|
||||
dba_->RemoveEdge(edge->impl_);
|
||||
return true;
|
||||
} catch (const mvcc::SerializationError &) {
|
||||
return storage::Error::SERIALIZATION_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
storage::Result<bool> DetachRemoveVertex(VertexAccessor *vertex_accessor) {
|
||||
try {
|
||||
dba_->DetachRemoveVertex(vertex_accessor->impl_);
|
||||
return true;
|
||||
} catch (const mvcc::SerializationError &) {
|
||||
return storage::Error::SERIALIZATION_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
storage::Result<bool> RemoveVertex(VertexAccessor *vertex_accessor) {
|
||||
try {
|
||||
if (!dba_->RemoveVertex(vertex_accessor->impl_))
|
||||
return storage::Error::VERTEX_HAS_EDGES;
|
||||
return true;
|
||||
} catch (const mvcc::SerializationError &) {
|
||||
return storage::Error::SERIALIZATION_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<VertexAccessor> FindVertex(storage::Gid gid,
|
||||
storage::View view) {
|
||||
auto maybe_vertex =
|
||||
dba_->FindVertexOptional(gid, view == storage::View::NEW);
|
||||
if (maybe_vertex) return VertexAccessor(*maybe_vertex);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto Vertices(storage::View view) {
|
||||
auto vertices = dba_->Vertices(view == storage::View::NEW);
|
||||
return VerticesIterable<decltype(vertices)>(std::move(vertices));
|
||||
}
|
||||
|
||||
auto Vertices(storage::View view, storage::Label label) {
|
||||
auto vertices = dba_->Vertices(label, view == storage::View::NEW);
|
||||
return VerticesIterable<decltype(vertices)>(std::move(vertices));
|
||||
}
|
||||
|
||||
auto Vertices(storage::View view, storage::Label label,
|
||||
storage::Property property, const PropertyValue &value) {
|
||||
auto vertices =
|
||||
dba_->Vertices(label, property, value, view == storage::View::NEW);
|
||||
return VerticesIterable<decltype(vertices)>(std::move(vertices));
|
||||
}
|
||||
|
||||
auto Vertices(storage::View view, storage::Label label,
|
||||
storage::Property property,
|
||||
const std::optional<utils::Bound<PropertyValue>> &lower,
|
||||
const std::optional<utils::Bound<PropertyValue>> &upper) {
|
||||
auto vertices = dba_->Vertices(label, property, lower, upper,
|
||||
view == storage::View::NEW);
|
||||
return VerticesIterable<decltype(vertices)>(std::move(vertices));
|
||||
}
|
||||
|
||||
storage::Property NameToProperty(const std::string_view &name) {
|
||||
return dba_->Property(std::string(name));
|
||||
}
|
||||
|
||||
storage::Label NameToLabel(const std::string_view &name) {
|
||||
return dba_->Label(std::string(name));
|
||||
}
|
||||
|
||||
storage::EdgeType NameToEdgeType(const std::string_view &name) {
|
||||
return dba_->EdgeType(std::string(name));
|
||||
}
|
||||
|
||||
const std::string &PropertyToName(storage::Property prop) const {
|
||||
return dba_->PropertyName(prop);
|
||||
}
|
||||
|
||||
const std::string &LabelToName(storage::Label label) const {
|
||||
return dba_->LabelName(label);
|
||||
}
|
||||
|
||||
const std::string &EdgeTypeToName(storage::EdgeType type) const {
|
||||
return dba_->EdgeTypeName(type);
|
||||
}
|
||||
|
||||
void AdvanceCommand() { dba_->AdvanceCommand(); }
|
||||
|
||||
bool CreateIndex(storage::Label label, storage::Property prop) {
|
||||
try {
|
||||
dba_->BuildIndex(label, prop);
|
||||
return true;
|
||||
} catch (const database::IndexExistsException &) {
|
||||
return false;
|
||||
} catch (const database::TransactionException &) {
|
||||
// TODO: What do we do with this? This cannot happen in v2
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
bool DropIndex(storage::Label label, storage::Property prop) {
|
||||
try {
|
||||
dba_->DeleteIndex(label, prop);
|
||||
return true;
|
||||
} catch (const database::TransactionException &) {
|
||||
// TODO: What do we do with this? This cannot happen in v2
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
bool LabelIndexExists(storage::Label label) const {
|
||||
// Label indices exist for all labels in the v1 storage.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LabelPropertyIndexExists(storage::Label label,
|
||||
storage::Property prop) const {
|
||||
return dba_->LabelPropertyIndexExists(label, prop);
|
||||
}
|
||||
|
||||
int64_t VerticesCount() const { return dba_->VerticesCount(); }
|
||||
|
||||
int64_t VerticesCount(storage::Label label) const {
|
||||
return dba_->VerticesCount(label);
|
||||
}
|
||||
|
||||
int64_t VerticesCount(storage::Label label,
|
||||
storage::Property property) const {
|
||||
return dba_->VerticesCount(label, property);
|
||||
}
|
||||
|
||||
int64_t VerticesCount(storage::Label label, storage::Property property,
|
||||
const PropertyValue &value) const {
|
||||
return dba_->VerticesCount(label, property, value);
|
||||
}
|
||||
|
||||
int64_t VerticesCount(
|
||||
storage::Label label, storage::Property property,
|
||||
const std::optional<utils::Bound<PropertyValue>> &lower,
|
||||
const std::optional<utils::Bound<PropertyValue>> &upper) const {
|
||||
return dba_->VerticesCount(label, property, lower, upper);
|
||||
}
|
||||
|
||||
auto StorageInfo() const { return dba_->StorageInfo(); }
|
||||
|
||||
auto IndexInfo() const { return dba_->IndexInfo(); }
|
||||
|
||||
auto GetIndicesKeys() const { return dba_->GetIndicesKeys(); }
|
||||
|
||||
auto ListUniqueConstraints() const { return dba_->ListUniqueConstraints(); }
|
||||
|
||||
void BuildUniqueConstraint(storage::Label label,
|
||||
const std::vector<storage::Property> &properties) {
|
||||
// TODO: Exceptions?
|
||||
return dba_->BuildUniqueConstraint(label, properties);
|
||||
}
|
||||
|
||||
void DeleteUniqueConstraint(
|
||||
storage::Label label, const std::vector<storage::Property> &properties) {
|
||||
// TODO: Exceptions?
|
||||
return dba_->DeleteUniqueConstraint(label, properties);
|
||||
}
|
||||
|
||||
#ifdef MG_SINGLE_NODE_HA
|
||||
auto raft() { return dba_->raft(); }
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace query
|
||||
|
||||
|
@ -77,11 +77,7 @@ void DumpPropertyValue(std::ostream *os, const storage::PropertyValue &value) {
|
||||
|
||||
void DumpProperties(
|
||||
std::ostream *os, query::DbAccessor *dba,
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
const std::map<storage::PropertyId, storage::PropertyValue> &store,
|
||||
#else
|
||||
const PropertyValueStore &store,
|
||||
#endif
|
||||
std::optional<uint64_t> property_id = std::nullopt) {
|
||||
*os << "{";
|
||||
if (property_id) {
|
||||
@ -174,7 +170,6 @@ void DumpEdge(std::ostream *os, query::DbAccessor *dba,
|
||||
*os << "]->(v);";
|
||||
}
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
void DumpLabelIndex(std::ostream *os, query::DbAccessor *dba,
|
||||
const storage::LabelId label) {
|
||||
*os << "CREATE INDEX ON :" << dba->LabelToName(label) << ";";
|
||||
@ -193,30 +188,10 @@ void DumpExistenceConstraint(std::ostream *os, query::DbAccessor *dba,
|
||||
*os << "CREATE CONSTRAINT ON (u:" << dba->LabelToName(label)
|
||||
<< ") ASSERT EXISTS (u." << dba->PropertyToName(property) << ");";
|
||||
}
|
||||
#else
|
||||
void DumpIndexKey(std::ostream *os, query::DbAccessor *dba,
|
||||
const database::LabelPropertyIndex::Key &key) {
|
||||
*os << "CREATE INDEX ON :" << dba->LabelToName(key.label_) << "("
|
||||
<< dba->PropertyToName(key.property_) << ");";
|
||||
}
|
||||
|
||||
void DumpUniqueConstraint(
|
||||
std::ostream *os, query::DbAccessor *dba,
|
||||
const storage::constraints::ConstraintEntry &constraint) {
|
||||
*os << "CREATE CONSTRAINT ON (u:" << dba->LabelToName(constraint.label)
|
||||
<< ") ASSERT ";
|
||||
utils::PrintIterable(*os, constraint.properties, ", ",
|
||||
[&dba](auto &os, const auto &property) {
|
||||
os << "u." << dba->PropertyToName(property);
|
||||
});
|
||||
*os << " IS UNIQUE;";
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
void DumpDatabaseToCypherQueries(query::DbAccessor *dba, AnyStream *stream) {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
{
|
||||
auto info = dba->ListAllIndices();
|
||||
for (const auto &item : info.label) {
|
||||
@ -238,18 +213,6 @@ void DumpDatabaseToCypherQueries(query::DbAccessor *dba, AnyStream *stream) {
|
||||
stream->Result({TypedValue(os.str())});
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (const auto &item : dba->GetIndicesKeys()) {
|
||||
std::ostringstream os;
|
||||
DumpIndexKey(&os, dba, item);
|
||||
stream->Result({TypedValue(os.str())});
|
||||
}
|
||||
for (const auto &item : dba->ListUniqueConstraints()) {
|
||||
std::ostringstream os;
|
||||
DumpUniqueConstraint(&os, dba, item);
|
||||
stream->Result({TypedValue(os.str())});
|
||||
}
|
||||
#endif
|
||||
|
||||
auto vertices = dba->Vertices(storage::View::OLD);
|
||||
bool internal_index_created = false;
|
||||
|
@ -675,7 +675,7 @@ PreparedQuery PrepareDumpQuery(
|
||||
PreparedQuery PrepareIndexQuery(
|
||||
ParsedQuery parsed_query, bool in_explicit_transaction,
|
||||
std::map<std::string, TypedValue> *summary,
|
||||
InterpreterContext *interpreter_context, DbAccessor *dba,
|
||||
InterpreterContext *interpreter_context,
|
||||
utils::MonotonicBufferResource *execution_memory) {
|
||||
if (in_explicit_transaction) {
|
||||
throw IndexInMulticommandTxException();
|
||||
@ -692,21 +692,12 @@ PreparedQuery PrepareIndexQuery(
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
auto label = interpreter_context->db->NameToLabel(index_query->label_.name);
|
||||
std::vector<storage::PropertyId> properties;
|
||||
properties.reserve(index_query->properties_.size());
|
||||
for (const auto &prop : index_query->properties_) {
|
||||
properties.push_back(interpreter_context->db->NameToProperty(prop.name));
|
||||
}
|
||||
#else
|
||||
auto label = dba->NameToLabel(index_query->label_.name);
|
||||
std::vector<storage::Property> properties;
|
||||
properties.reserve(index_query->properties_.size());
|
||||
for (const auto &prop : index_query->properties_) {
|
||||
properties.push_back(dba->NameToProperty(prop.name));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (properties.size() > 1) {
|
||||
throw utils::NotYetImplemented("index on multiple properties");
|
||||
@ -714,7 +705,6 @@ PreparedQuery PrepareIndexQuery(
|
||||
|
||||
switch (index_query->action_) {
|
||||
case IndexQuery::Action::CREATE: {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
handler = [interpreter_context, label, properties = std::move(properties),
|
||||
invalidate_plan_cache = std::move(invalidate_plan_cache)] {
|
||||
if (properties.empty()) {
|
||||
@ -725,28 +715,9 @@ PreparedQuery PrepareIndexQuery(
|
||||
}
|
||||
invalidate_plan_cache();
|
||||
};
|
||||
#else
|
||||
handler = [dba, label, properties = std::move(properties),
|
||||
invalidate_plan_cache = std::move(invalidate_plan_cache)] {
|
||||
// Old storage creates label index by default.
|
||||
if (properties.empty()) return;
|
||||
try {
|
||||
CHECK(properties.size() == 1U);
|
||||
dba->CreateIndex(label, properties[0]);
|
||||
invalidate_plan_cache();
|
||||
} catch (const database::ConstraintViolationException &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
} catch (const database::IndexExistsException &e) {
|
||||
// Ignore creating an existing index.
|
||||
} catch (const database::TransactionException &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
}
|
||||
};
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case IndexQuery::Action::DROP: {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
handler = [interpreter_context, label, properties = std::move(properties),
|
||||
invalidate_plan_cache = std::move(invalidate_plan_cache)] {
|
||||
if (properties.empty()) {
|
||||
@ -757,20 +728,6 @@ PreparedQuery PrepareIndexQuery(
|
||||
}
|
||||
invalidate_plan_cache();
|
||||
};
|
||||
#else
|
||||
handler = [dba, label, properties = std::move(properties),
|
||||
invalidate_plan_cache = std::move(invalidate_plan_cache)] {
|
||||
if (properties.empty())
|
||||
throw QueryRuntimeException("Label index cannot be dropped!");
|
||||
try {
|
||||
CHECK(properties.size() == 1U);
|
||||
dba->DropIndex(label, properties[0]);
|
||||
invalidate_plan_cache();
|
||||
} catch (const database::TransactionException &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
}
|
||||
};
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -779,11 +736,7 @@ PreparedQuery PrepareIndexQuery(
|
||||
std::move(parsed_query.required_privileges),
|
||||
[handler = std::move(handler)](AnyStream *stream) {
|
||||
handler();
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
return QueryHandlerResult::NOTHING;
|
||||
#else
|
||||
return QueryHandlerResult::COMMIT;
|
||||
#endif
|
||||
}};
|
||||
}
|
||||
|
||||
@ -836,11 +789,7 @@ PreparedQuery PrepareAuthQuery(
|
||||
PreparedQuery PrepareInfoQuery(
|
||||
ParsedQuery parsed_query, std::map<std::string, TypedValue> *summary,
|
||||
InterpreterContext *interpreter_context,
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
storage::Storage *db,
|
||||
#else
|
||||
DbAccessor *dba,
|
||||
#endif
|
||||
utils::MonotonicBufferResource *execution_memory) {
|
||||
auto *info_query = utils::Downcast<InfoQuery>(parsed_query.query);
|
||||
std::vector<std::string> header;
|
||||
@ -850,7 +799,7 @@ PreparedQuery PrepareInfoQuery(
|
||||
|
||||
switch (info_query->info_type_) {
|
||||
case InfoQuery::InfoType::STORAGE:
|
||||
#if defined(MG_SINGLE_NODE_V2)
|
||||
#ifndef MG_SINGLE_NODE_HA
|
||||
header = {"storage info", "value"};
|
||||
handler = [db] {
|
||||
auto info = db->GetInfo();
|
||||
@ -866,18 +815,7 @@ PreparedQuery PrepareInfoQuery(
|
||||
TypedValue(static_cast<int64_t>(info.disk_usage))}};
|
||||
return std::pair{results, QueryHandlerResult::COMMIT};
|
||||
};
|
||||
#elif defined(MG_SINGLE_NODE)
|
||||
header = {"storage info", "value"};
|
||||
handler = [dba] {
|
||||
auto info = dba->StorageInfo();
|
||||
std::vector<std::vector<TypedValue>> results;
|
||||
results.reserve(info.size());
|
||||
for (const auto &pair : info) {
|
||||
results.push_back({TypedValue(pair.first), TypedValue(pair.second)});
|
||||
}
|
||||
return std::pair{results, QueryHandlerResult::COMMIT};
|
||||
};
|
||||
#elif defined(MG_SINGLE_NODE_HA)
|
||||
#else
|
||||
header = {"server id", "storage info", "value"};
|
||||
handler = [dba] {
|
||||
auto info = dba->StorageInfo();
|
||||
@ -892,12 +830,9 @@ PreparedQuery PrepareInfoQuery(
|
||||
}
|
||||
return std::pair{results, QueryHandlerResult::COMMIT};
|
||||
};
|
||||
#else
|
||||
throw utils::NotYetImplemented("storage info");
|
||||
#endif
|
||||
break;
|
||||
case InfoQuery::InfoType::INDEX:
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
header = {"index type", "label", "property"};
|
||||
handler = [interpreter_context] {
|
||||
auto *db = interpreter_context->db;
|
||||
@ -916,21 +851,7 @@ PreparedQuery PrepareInfoQuery(
|
||||
return std::pair{results, QueryHandlerResult::NOTHING};
|
||||
};
|
||||
break;
|
||||
#else
|
||||
header = {"created index"};
|
||||
handler = [dba] {
|
||||
auto info = dba->IndexInfo();
|
||||
std::vector<std::vector<TypedValue>> results;
|
||||
results.reserve(info.size());
|
||||
for (const auto &index : info) {
|
||||
results.push_back({TypedValue(index)});
|
||||
}
|
||||
return std::pair{results, QueryHandlerResult::COMMIT};
|
||||
};
|
||||
break;
|
||||
#endif
|
||||
case InfoQuery::InfoType::CONSTRAINT:
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
header = {"constraint type", "label", "properties"};
|
||||
handler = [interpreter_context] {
|
||||
auto *db = interpreter_context->db;
|
||||
@ -945,26 +866,6 @@ PreparedQuery PrepareInfoQuery(
|
||||
return std::pair{results, QueryHandlerResult::NOTHING};
|
||||
};
|
||||
break;
|
||||
#else
|
||||
header = {"constraint type", "label", "properties"};
|
||||
handler = [dba] {
|
||||
std::vector<std::vector<TypedValue>> results;
|
||||
for (auto &e : dba->ListUniqueConstraints()) {
|
||||
std::vector<std::string> property_names(e.properties.size());
|
||||
std::transform(
|
||||
e.properties.begin(), e.properties.end(), property_names.begin(),
|
||||
[dba](const auto &p) { return dba->PropertyToName(p); });
|
||||
|
||||
std::vector<TypedValue> constraint{
|
||||
TypedValue("unique"), TypedValue(dba->LabelToName(e.label)),
|
||||
TypedValue(utils::Join(property_names, ","))};
|
||||
|
||||
results.emplace_back(constraint);
|
||||
}
|
||||
return std::pair{results, QueryHandlerResult::COMMIT};
|
||||
};
|
||||
break;
|
||||
#endif
|
||||
case InfoQuery::InfoType::RAFT:
|
||||
#if defined(MG_SINGLE_NODE_HA)
|
||||
header = {"info", "value"};
|
||||
@ -998,12 +899,11 @@ PreparedQuery PrepareInfoQuery(
|
||||
|
||||
PreparedQuery PrepareConstraintQuery(
|
||||
ParsedQuery parsed_query, std::map<std::string, TypedValue> *summary,
|
||||
InterpreterContext *interpreter_context, DbAccessor *dba,
|
||||
InterpreterContext *interpreter_context,
|
||||
utils::MonotonicBufferResource *execution_memory) {
|
||||
auto *constraint_query = utils::Downcast<ConstraintQuery>(parsed_query.query);
|
||||
std::function<void()> handler;
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
auto label = interpreter_context->db->NameToLabel(
|
||||
constraint_query->constraint_.label.name);
|
||||
std::vector<storage::PropertyId> properties;
|
||||
@ -1011,14 +911,6 @@ PreparedQuery PrepareConstraintQuery(
|
||||
for (const auto &prop : constraint_query->constraint_.properties) {
|
||||
properties.push_back(interpreter_context->db->NameToProperty(prop.name));
|
||||
}
|
||||
#else
|
||||
auto label = dba->NameToLabel(constraint_query->constraint_.label.name);
|
||||
std::vector<storage::Property> properties;
|
||||
properties.reserve(constraint_query->constraint_.properties.size());
|
||||
for (const auto &prop : constraint_query->constraint_.properties) {
|
||||
properties.push_back(dba->NameToProperty(prop.name));
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (constraint_query->action_type_) {
|
||||
case ConstraintQuery::ActionType::CREATE: {
|
||||
@ -1026,7 +918,6 @@ PreparedQuery PrepareConstraintQuery(
|
||||
case Constraint::Type::NODE_KEY:
|
||||
throw utils::NotYetImplemented("Node key constraints");
|
||||
case Constraint::Type::EXISTS:
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
if (properties.empty() || properties.size() > 1) {
|
||||
throw SyntaxException(
|
||||
"Exactly one property must be used for existence constraints.");
|
||||
@ -1048,26 +939,8 @@ PreparedQuery PrepareConstraintQuery(
|
||||
}
|
||||
};
|
||||
break;
|
||||
#else
|
||||
throw utils::NotYetImplemented("Existence constraints");
|
||||
#endif
|
||||
case Constraint::Type::UNIQUE:
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
throw utils::NotYetImplemented("Unique constraints");
|
||||
#else
|
||||
handler = [dba, label, properties = std::move(properties)] {
|
||||
try {
|
||||
dba->BuildUniqueConstraint(label, properties);
|
||||
} catch (const database::ConstraintViolationException &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
} catch (const database::TransactionException &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
} catch (const mvcc::SerializationError &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
}
|
||||
};
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
case ConstraintQuery::ActionType::DROP: {
|
||||
@ -1075,7 +948,6 @@ PreparedQuery PrepareConstraintQuery(
|
||||
case Constraint::Type::NODE_KEY:
|
||||
throw utils::NotYetImplemented("Node key constraints");
|
||||
case Constraint::Type::EXISTS:
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
if (properties.empty() || properties.size() > 1) {
|
||||
throw SyntaxException(
|
||||
"Exactly one property must be used for existence constraints.");
|
||||
@ -1087,23 +959,8 @@ PreparedQuery PrepareConstraintQuery(
|
||||
return std::vector<std::vector<TypedValue>>();
|
||||
};
|
||||
break;
|
||||
#else
|
||||
throw utils::NotYetImplemented("Existence constraints");
|
||||
#endif
|
||||
case Constraint::Type::UNIQUE:
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
throw utils::NotYetImplemented("Unique constraints");
|
||||
#else
|
||||
handler = [dba, label, properties = std::move(properties)] {
|
||||
try {
|
||||
dba->DeleteUniqueConstraint(label, properties);
|
||||
return std::vector<std::vector<TypedValue>>();
|
||||
} catch (const database::TransactionException &e) {
|
||||
throw QueryRuntimeException(e.what());
|
||||
}
|
||||
};
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
}
|
||||
@ -1165,7 +1022,6 @@ Interpreter::Prepare(
|
||||
summary_["parsing_time"] = parsing_timer.Elapsed().count();
|
||||
|
||||
// Some queries require an active transaction in order to be prepared.
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
if (!in_explicit_transaction_ &&
|
||||
!utils::Downcast<IndexQuery>(parsed_query.query) &&
|
||||
!utils::Downcast<DumpQuery>(parsed_query.query) &&
|
||||
@ -1174,13 +1030,6 @@ Interpreter::Prepare(
|
||||
db_accessor_.emplace(interpreter_context_->db->Access());
|
||||
execution_db_accessor_.emplace(&*db_accessor_);
|
||||
}
|
||||
#else
|
||||
if (!in_explicit_transaction_ &&
|
||||
!utils::Downcast<DumpQuery>(parsed_query.query)) {
|
||||
db_accessor_.emplace(interpreter_context_->db->Access());
|
||||
execution_db_accessor_.emplace(&*db_accessor_);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MG_SINGLE_NODE_HA
|
||||
{
|
||||
@ -1213,38 +1062,21 @@ Interpreter::Prepare(
|
||||
PrepareDumpQuery(std::move(parsed_query), &summary_,
|
||||
interpreter_context_, &execution_memory_);
|
||||
} else if (utils::Downcast<IndexQuery>(parsed_query.query)) {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
DbAccessor *dba = nullptr;
|
||||
#else
|
||||
auto dba = &*execution_db_accessor_;
|
||||
#endif
|
||||
prepared_query = PrepareIndexQuery(
|
||||
std::move(parsed_query), in_explicit_transaction_, &summary_,
|
||||
interpreter_context_, dba, &execution_memory_);
|
||||
interpreter_context_, &execution_memory_);
|
||||
} else if (utils::Downcast<AuthQuery>(parsed_query.query)) {
|
||||
prepared_query = PrepareAuthQuery(
|
||||
std::move(parsed_query), in_explicit_transaction_, &summary_,
|
||||
interpreter_context_, &*execution_db_accessor_, &execution_memory_);
|
||||
} else if (utils::Downcast<InfoQuery>(parsed_query.query)) {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
prepared_query = PrepareInfoQuery(
|
||||
std::move(parsed_query), &summary_, interpreter_context_,
|
||||
interpreter_context_->db, &execution_memory_);
|
||||
#else
|
||||
auto dba = &*execution_db_accessor_;
|
||||
prepared_query =
|
||||
PrepareInfoQuery(std::move(parsed_query), &summary_,
|
||||
interpreter_context_, dba, &execution_memory_);
|
||||
#endif
|
||||
} else if (utils::Downcast<ConstraintQuery>(parsed_query.query)) {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
DbAccessor *dba = nullptr;
|
||||
#else
|
||||
auto dba = &*execution_db_accessor_;
|
||||
#endif
|
||||
prepared_query =
|
||||
PrepareConstraintQuery(std::move(parsed_query), &summary_,
|
||||
interpreter_context_, dba, &execution_memory_);
|
||||
interpreter_context_, &execution_memory_);
|
||||
} else {
|
||||
LOG(FATAL) << "Should not get here -- unknown query type!";
|
||||
}
|
||||
@ -1274,7 +1106,6 @@ void Interpreter::Commit() {
|
||||
prepared_query_ = std::nullopt;
|
||||
execution_memory_.Release();
|
||||
if (!db_accessor_) return;
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
auto maybe_constraint_violation = db_accessor_->Commit();
|
||||
if (maybe_constraint_violation.HasError()) {
|
||||
const auto &constraint_violation = maybe_constraint_violation.GetError();
|
||||
@ -1288,9 +1119,6 @@ void Interpreter::Commit() {
|
||||
"Unable to commit due to existence constraint violation on :{}({}).",
|
||||
label_name, property_name);
|
||||
}
|
||||
#else
|
||||
db_accessor_->Commit();
|
||||
#endif
|
||||
execution_db_accessor_ = std::nullopt;
|
||||
db_accessor_ = std::nullopt;
|
||||
}
|
||||
|
@ -184,20 +184,12 @@ struct PlanCacheEntry {
|
||||
* been passed to an `Interpreter` instance.
|
||||
*/
|
||||
struct InterpreterContext {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
explicit InterpreterContext(storage::Storage *db)
|
||||
#else
|
||||
explicit InterpreterContext(database::GraphDb *db)
|
||||
#endif
|
||||
: db(db) {
|
||||
CHECK(db) << "Storage must not be NULL";
|
||||
}
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
storage::Storage *db;
|
||||
#else
|
||||
database::GraphDb *db;
|
||||
#endif
|
||||
|
||||
// ANTLR has singleton instance that is shared between threads. It is
|
||||
// protected by locks inside of ANTLR. Unfortunately, they are not protected
|
||||
@ -281,11 +273,7 @@ class Interpreter final {
|
||||
std::optional<PreparedQuery> prepared_query_;
|
||||
std::map<std::string, TypedValue> summary_;
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
std::optional<storage::Storage::Accessor> db_accessor_;
|
||||
#else
|
||||
std::optional<database::GraphDbAccessor> db_accessor_;
|
||||
#endif
|
||||
std::optional<DbAccessor> execution_db_accessor_;
|
||||
bool in_explicit_transaction_{false};
|
||||
bool expect_rollback_{false};
|
||||
|
@ -1,14 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
#include "storage/v2/id_types.hpp"
|
||||
namespace storage {
|
||||
using EdgeType = EdgeTypeId;
|
||||
using Label = LabelId;
|
||||
using Property = PropertyId;
|
||||
}
|
||||
#else
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
@ -256,5 +247,3 @@ struct hash<storage::Gid> {
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
|
@ -1,10 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
#include "storage/v2/edge_accessor.hpp"
|
||||
using EdgeAccessor = storage::EdgeAccessor;
|
||||
#endif
|
||||
|
||||
#ifdef MG_SINGLE_NODE
|
||||
#include "storage/single_node/edge_accessor.hpp"
|
||||
#endif
|
||||
|
@ -1,10 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
#include "storage/v2/vertex_accessor.hpp"
|
||||
using VertexAccessor = storage::VertexAccessor;
|
||||
#endif
|
||||
|
||||
#ifdef MG_SINGLE_NODE
|
||||
#include "storage/single_node/vertex_accessor.hpp"
|
||||
#endif
|
||||
|
@ -180,15 +180,9 @@ TEST(CypherType, MapSatisfiesType) {
|
||||
}
|
||||
|
||||
TEST(CypherType, VertexSatisfiesType) {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
storage::Storage db;
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
#else
|
||||
database::GraphDb db;
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
#endif
|
||||
auto vertex = dba.InsertVertex();
|
||||
mgp_memory memory{utils::NewDeleteResource()};
|
||||
utils::Allocator<mgp_vertex> alloc(memory.impl);
|
||||
@ -206,15 +200,9 @@ TEST(CypherType, VertexSatisfiesType) {
|
||||
}
|
||||
|
||||
TEST(CypherType, EdgeSatisfiesType) {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
storage::Storage db;
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
#else
|
||||
database::GraphDb db;
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
#endif
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto edge = *dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("edge_type"));
|
||||
@ -234,15 +222,9 @@ TEST(CypherType, EdgeSatisfiesType) {
|
||||
}
|
||||
|
||||
TEST(CypherType, PathSatisfiesType) {
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
storage::Storage db;
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
#else
|
||||
database::GraphDb db;
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
#endif
|
||||
auto v1 = dba.InsertVertex();
|
||||
auto v2 = dba.InsertVertex();
|
||||
auto edge = *dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("edge_type"));
|
||||
|
Loading…
Reference in New Issue
Block a user