Migrate tests to storage v2 part 1
Reviewers: teon.banek Reviewed By: teon.banek Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D2554
This commit is contained in:
parent
ae0be9032e
commit
9cc10e131d
@ -7,7 +7,7 @@
|
||||
#include "communication/bolt/v1/value.hpp"
|
||||
#include "glue/communication.hpp"
|
||||
#include "query/typed_value.hpp"
|
||||
#include "storage/v2/view.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
#include "utils/algorithm.hpp"
|
||||
|
||||
// TODO: Why is this here?! It's only used in tests and query/repl.cpp
|
||||
@ -20,7 +20,8 @@
|
||||
*/
|
||||
class ResultStreamFaker {
|
||||
public:
|
||||
ResultStreamFaker() = default;
|
||||
explicit ResultStreamFaker(storage::Storage *store) : store_(store) {}
|
||||
|
||||
ResultStreamFaker(const ResultStreamFaker &) = delete;
|
||||
ResultStreamFaker &operator=(const ResultStreamFaker &) = delete;
|
||||
ResultStreamFaker(ResultStreamFaker &&) = default;
|
||||
@ -36,7 +37,9 @@ class ResultStreamFaker {
|
||||
std::vector<communication::bolt::Value> bvalues;
|
||||
bvalues.reserve(values.size());
|
||||
for (const auto &value : values) {
|
||||
bvalues.push_back(glue::ToBoltValue(value, storage::View::NEW));
|
||||
auto maybe_value = glue::ToBoltValue(value, *store_, storage::View::NEW);
|
||||
CHECK(maybe_value.HasValue());
|
||||
bvalues.push_back(std::move(*maybe_value));
|
||||
}
|
||||
results_.push_back(std::move(bvalues));
|
||||
}
|
||||
@ -49,8 +52,10 @@ class ResultStreamFaker {
|
||||
void Summary(const std::map<std::string, query::TypedValue> &summary) {
|
||||
std::map<std::string, communication::bolt::Value> bsummary;
|
||||
for (const auto &item : summary) {
|
||||
bsummary.insert(
|
||||
{item.first, glue::ToBoltValue(item.second, storage::View::NEW)});
|
||||
auto maybe_value =
|
||||
glue::ToBoltValue(item.second, *store_, storage::View::NEW);
|
||||
CHECK(maybe_value.HasValue());
|
||||
bsummary.insert({item.first, std::move(*maybe_value)});
|
||||
}
|
||||
summary_ = std::move(bsummary);
|
||||
}
|
||||
@ -129,6 +134,7 @@ class ResultStreamFaker {
|
||||
}
|
||||
|
||||
private:
|
||||
storage::Storage *store_;
|
||||
// the data that the record stream can accept
|
||||
std::vector<std::string> header_;
|
||||
std::vector<std::vector<communication::bolt::Value>> results_;
|
||||
|
@ -604,6 +604,12 @@ class DbAccessor final {
|
||||
|
||||
void AdvanceCommand() { accessor_->AdvanceCommand(); }
|
||||
|
||||
utils::BasicResult<storage::ExistenceConstraintViolation, void> Commit() {
|
||||
return accessor_->Commit();
|
||||
}
|
||||
|
||||
void Abort() { accessor_->Abort(); }
|
||||
|
||||
bool MustAbort() const { return false; }
|
||||
|
||||
bool LabelIndexExists(storage::Label label) const {
|
||||
|
@ -34,19 +34,19 @@ add_benchmark(data_structures/ring_buffer.cpp)
|
||||
target_link_libraries(${test_prefix}ring_buffer mg-single-node kvstore_dummy_lib)
|
||||
|
||||
add_benchmark(query/eval.cpp)
|
||||
target_link_libraries(${test_prefix}eval mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}eval mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_benchmark(query/execution.cpp)
|
||||
target_link_libraries(${test_prefix}execution mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}execution mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_benchmark(query/planner.cpp)
|
||||
target_link_libraries(${test_prefix}planner mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}planner mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_benchmark(query/profile.cpp)
|
||||
target_link_libraries(${test_prefix}profile mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}profile mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_benchmark(query/stripped.cpp)
|
||||
target_link_libraries(${test_prefix}stripped mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}stripped mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_benchmark(edge_storage.cpp)
|
||||
target_link_libraries(${test_prefix}edge_storage mg-single-node kvstore_dummy_lib)
|
||||
@ -73,7 +73,7 @@ add_benchmark(tx_engine.cpp)
|
||||
target_link_libraries(${test_prefix}tx_engine mg-single-node kvstore_dummy_lib)
|
||||
|
||||
add_benchmark(expansion.cpp)
|
||||
target_link_libraries(${test_prefix}expansion mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}expansion mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_benchmark(storage_v2_gc.cpp)
|
||||
target_link_libraries(${test_prefix}storage_v2_gc mg-storage-v2)
|
||||
|
@ -3,55 +3,56 @@
|
||||
#include <glog/logging.h>
|
||||
|
||||
#include "communication/result_stream_faker.hpp"
|
||||
#include "database/single_node/graph_db.hpp"
|
||||
#include "database/single_node/graph_db_accessor.hpp"
|
||||
#include "query/interpreter.hpp"
|
||||
#include "query/typed_value.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
|
||||
class ExpansionBenchFixture : public benchmark::Fixture {
|
||||
protected:
|
||||
// GraphDb shouldn't be global constructed/destructed. See
|
||||
// documentation in database/single_node/graph_db.hpp for details.
|
||||
std::optional<database::GraphDb> db_;
|
||||
std::optional<query::InterpreterContext> interpreter_context_;
|
||||
std::optional<query::Interpreter> interpreter_;
|
||||
std::optional<storage::Storage> db;
|
||||
std::optional<query::InterpreterContext> interpreter_context;
|
||||
std::optional<query::Interpreter> interpreter;
|
||||
|
||||
void SetUp(const benchmark::State &state) override {
|
||||
db_.emplace();
|
||||
auto dba = db_->Access();
|
||||
for (int i = 0; i < state.range(0); i++) dba.InsertVertex();
|
||||
db.emplace();
|
||||
|
||||
// the fixed part is one vertex expanding to 1000 others
|
||||
auto start = dba.InsertVertex();
|
||||
start.add_label(dba.Label("Starting"));
|
||||
auto edge_type = dba.EdgeType("edge_type");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
auto dest = dba.InsertVertex();
|
||||
dba.InsertEdge(start, dest, edge_type);
|
||||
auto label = db->NameToLabel("Starting");
|
||||
|
||||
{
|
||||
auto dba = db->Access();
|
||||
for (int i = 0; i < state.range(0); i++) dba.CreateVertex();
|
||||
|
||||
// the fixed part is one vertex expanding to 1000 others
|
||||
auto start = dba.CreateVertex();
|
||||
CHECK(start.AddLabel(label).HasValue());
|
||||
auto edge_type = dba.NameToEdgeType("edge_type");
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
auto dest = dba.CreateVertex();
|
||||
CHECK(dba.CreateEdge(&start, &dest, edge_type).HasValue());
|
||||
}
|
||||
CHECK(!dba.Commit().HasError());
|
||||
}
|
||||
dba.Commit();
|
||||
|
||||
interpreter_context_.emplace(&*db_);
|
||||
interpreter_.emplace(&*interpreter_context_);
|
||||
CHECK(db->CreateIndex(label));
|
||||
|
||||
interpreter_context.emplace(&*db);
|
||||
interpreter.emplace(&*interpreter_context);
|
||||
}
|
||||
|
||||
void TearDown(const benchmark::State &) override {
|
||||
auto dba = db_->Access();
|
||||
for (auto vertex : dba.Vertices(false)) dba.DetachRemoveVertex(vertex);
|
||||
dba.Commit();
|
||||
db_ = std::nullopt;
|
||||
interpreter = std::nullopt;
|
||||
interpreter_context = std::nullopt;
|
||||
db = std::nullopt;
|
||||
}
|
||||
|
||||
auto &interpreter() { return *interpreter_; }
|
||||
};
|
||||
|
||||
BENCHMARK_DEFINE_F(ExpansionBenchFixture, Match)(benchmark::State &state) {
|
||||
auto query = "MATCH (s:Starting) return s";
|
||||
|
||||
while (state.KeepRunning()) {
|
||||
ResultStreamFaker results;
|
||||
interpreter().Prepare(query, {});
|
||||
interpreter().PullAll(&results);
|
||||
ResultStreamFaker results(&*db);
|
||||
interpreter->Prepare(query, {});
|
||||
interpreter->PullAll(&results);
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,9 +65,9 @@ BENCHMARK_DEFINE_F(ExpansionBenchFixture, Expand)(benchmark::State &state) {
|
||||
auto query = "MATCH (s:Starting) WITH s MATCH (s)--(d) RETURN count(d)";
|
||||
|
||||
while (state.KeepRunning()) {
|
||||
ResultStreamFaker results;
|
||||
interpreter().Prepare(query, {});
|
||||
interpreter().PullAll(&results);
|
||||
ResultStreamFaker results(&*db);
|
||||
interpreter->Prepare(query, {});
|
||||
interpreter->PullAll(&results);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "query/db_accessor.hpp"
|
||||
#include "query/interpret/eval.hpp"
|
||||
#include "query/interpreter.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
|
||||
// The following classes are wrappers for utils::MemoryResource, so that we can
|
||||
// use BENCHMARK_TEMPLATE
|
||||
@ -26,9 +27,9 @@ static void MapLiteral(benchmark::State &state) {
|
||||
query::SymbolTable symbol_table;
|
||||
TMemory memory;
|
||||
query::Frame frame(symbol_table.max_position(), memory.get());
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
query::DbAccessor execution_dba(&dba);
|
||||
storage::Storage db;
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
std::unordered_map<query::PropertyIx, query::Expression *> elements;
|
||||
for (int64_t i = 0; i < state.range(0); ++i) {
|
||||
elements.emplace(ast.GetPropertyIx("prop" + std::to_string(i)),
|
||||
@ -37,9 +38,9 @@ static void MapLiteral(benchmark::State &state) {
|
||||
auto *expr = ast.Create<query::MapLiteral>(elements);
|
||||
query::EvaluationContext evaluation_context{memory.get()};
|
||||
evaluation_context.properties =
|
||||
query::NamesToProperties(ast.properties_, &execution_dba);
|
||||
query::NamesToProperties(ast.properties_, &dba);
|
||||
query::ExpressionEvaluator evaluator(&frame, symbol_table, evaluation_context,
|
||||
&execution_dba, storage::View::NEW);
|
||||
&dba, storage::View::NEW);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(expr->Accept(evaluator));
|
||||
}
|
||||
@ -61,17 +62,17 @@ static void AdditionOperator(benchmark::State &state) {
|
||||
query::SymbolTable symbol_table;
|
||||
TMemory memory;
|
||||
query::Frame frame(symbol_table.max_position(), memory.get());
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
storage::Storage db;
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
query::Expression *expr = ast.Create<query::PrimitiveLiteral>(0);
|
||||
for (int64_t i = 0; i < state.range(0); ++i) {
|
||||
expr = ast.Create<query::AdditionOperator>(
|
||||
expr, ast.Create<query::PrimitiveLiteral>(i));
|
||||
}
|
||||
query::EvaluationContext evaluation_context{memory.get()};
|
||||
query::DbAccessor execution_dba(&dba);
|
||||
query::ExpressionEvaluator evaluator(&frame, symbol_table, evaluation_context,
|
||||
&execution_dba, storage::View::NEW);
|
||||
&dba, storage::View::NEW);
|
||||
while (state.KeepRunning()) {
|
||||
benchmark::DoNotOptimize(expr->Accept(evaluator));
|
||||
}
|
||||
|
@ -4,13 +4,12 @@
|
||||
#include <benchmark/benchmark.h>
|
||||
|
||||
#include "communication/result_stream_faker.hpp"
|
||||
#include "database/graph_db.hpp"
|
||||
#include "database/graph_db_accessor.hpp"
|
||||
#include "query/frontend/opencypher/parser.hpp"
|
||||
#include "query/frontend/semantic/required_privileges.hpp"
|
||||
#include "query/frontend/semantic/symbol_generator.hpp"
|
||||
#include "query/interpreter.hpp"
|
||||
#include "query/plan/planner.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
|
||||
// The following classes are wrappers for utils::MemoryResource, so that we can
|
||||
// use BENCHMARK_TEMPLATE
|
||||
@ -40,46 +39,53 @@ class PoolResource final {
|
||||
void Reset() { memory_.Release(); }
|
||||
};
|
||||
|
||||
static void AddVertices(database::GraphDb *db, int vertex_count) {
|
||||
static void AddVertices(storage::Storage *db, int vertex_count) {
|
||||
auto dba = db->Access();
|
||||
for (int i = 0; i < vertex_count; i++) dba.InsertVertex();
|
||||
dba.Commit();
|
||||
for (int i = 0; i < vertex_count; i++) dba.CreateVertex();
|
||||
CHECK(!dba.Commit().HasError());
|
||||
}
|
||||
|
||||
static const char *kStartLabel = "start";
|
||||
|
||||
static void AddStarGraph(database::GraphDb *db, int spoke_count, int depth) {
|
||||
auto dba = db->Access();
|
||||
VertexAccessor center_vertex = dba.InsertVertex();
|
||||
center_vertex.add_label(dba.Label(kStartLabel));
|
||||
for (int i = 0; i < spoke_count; ++i) {
|
||||
VertexAccessor prev_vertex = center_vertex;
|
||||
for (int j = 0; j < depth; ++j) {
|
||||
auto dest = dba.InsertVertex();
|
||||
dba.InsertEdge(prev_vertex, dest, dba.EdgeType("Type"));
|
||||
prev_vertex = dest;
|
||||
static void AddStarGraph(storage::Storage *db, int spoke_count, int depth) {
|
||||
{
|
||||
auto dba = db->Access();
|
||||
auto center_vertex = dba.CreateVertex();
|
||||
CHECK(center_vertex.AddLabel(dba.NameToLabel(kStartLabel)).HasValue());
|
||||
for (int i = 0; i < spoke_count; ++i) {
|
||||
auto prev_vertex = center_vertex;
|
||||
for (int j = 0; j < depth; ++j) {
|
||||
auto dest = dba.CreateVertex();
|
||||
CHECK(dba.CreateEdge(&prev_vertex, &dest, dba.NameToEdgeType("Type"))
|
||||
.HasValue());
|
||||
prev_vertex = dest;
|
||||
}
|
||||
}
|
||||
CHECK(!dba.Commit().HasError());
|
||||
}
|
||||
dba.Commit();
|
||||
CHECK(db->CreateIndex(db->NameToLabel(kStartLabel)));
|
||||
}
|
||||
|
||||
static void AddTree(database::GraphDb *db, int vertex_count) {
|
||||
auto dba = db->Access();
|
||||
std::vector<VertexAccessor> vertices;
|
||||
vertices.reserve(vertex_count);
|
||||
auto root = dba.InsertVertex();
|
||||
root.add_label(dba.Label(kStartLabel));
|
||||
vertices.push_back(root);
|
||||
// NOLINTNEXTLINE(cert-msc32-c,cert-msc51-cpp)
|
||||
std::mt19937_64 rg(42);
|
||||
for (int i = 1; i < vertex_count; ++i) {
|
||||
auto v = dba.InsertVertex();
|
||||
std::uniform_int_distribution<> dis(0U, vertices.size() - 1U);
|
||||
auto &parent = vertices.at(dis(rg));
|
||||
dba.InsertEdge(parent, v, dba.EdgeType("Type"));
|
||||
vertices.push_back(v);
|
||||
static void AddTree(storage::Storage *db, int vertex_count) {
|
||||
{
|
||||
auto dba = db->Access();
|
||||
std::vector<storage::VertexAccessor> vertices;
|
||||
vertices.reserve(vertex_count);
|
||||
auto root = dba.CreateVertex();
|
||||
CHECK(root.AddLabel(dba.NameToLabel(kStartLabel)).HasValue());
|
||||
vertices.push_back(root);
|
||||
// NOLINTNEXTLINE(cert-msc32-c,cert-msc51-cpp)
|
||||
std::mt19937_64 rg(42);
|
||||
for (int i = 1; i < vertex_count; ++i) {
|
||||
auto v = dba.CreateVertex();
|
||||
std::uniform_int_distribution<> dis(0U, vertices.size() - 1U);
|
||||
auto &parent = vertices.at(dis(rg));
|
||||
CHECK(dba.CreateEdge(&parent, &v, dba.NameToEdgeType("Type")).HasValue());
|
||||
vertices.push_back(v);
|
||||
}
|
||||
CHECK(!dba.Commit().HasError());
|
||||
}
|
||||
dba.Commit();
|
||||
CHECK(db->CreateIndex(db->NameToLabel(kStartLabel)));
|
||||
}
|
||||
|
||||
static query::CypherQuery *ParseCypherQuery(const std::string &query_string,
|
||||
@ -98,23 +104,23 @@ template <class TMemory>
|
||||
static void Distinct(benchmark::State &state) {
|
||||
query::AstStorage ast;
|
||||
query::Parameters parameters;
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
AddVertices(&db, state.range(0));
|
||||
auto dba = db.Access();
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
auto query_string = "MATCH (s) RETURN DISTINCT s";
|
||||
auto *cypher_query = ParseCypherQuery(query_string, &ast);
|
||||
auto symbol_table = query::MakeSymbolTable(cypher_query);
|
||||
query::DbAccessor execution_dba(&dba);
|
||||
auto context = query::plan::MakePlanningContext(&ast, &symbol_table,
|
||||
cypher_query, &execution_dba);
|
||||
auto context =
|
||||
query::plan::MakePlanningContext(&ast, &symbol_table, cypher_query, &dba);
|
||||
auto plan_and_cost =
|
||||
query::plan::MakeLogicalPlan(&context, parameters, false);
|
||||
ResultStreamFaker results;
|
||||
ResultStreamFaker results(&db);
|
||||
// We need to only set the memory for temporary (per pull) evaluations
|
||||
TMemory per_pull_memory;
|
||||
query::EvaluationContext evaluation_context{per_pull_memory.get()};
|
||||
while (state.KeepRunning()) {
|
||||
query::ExecutionContext execution_context{&execution_dba, symbol_table,
|
||||
query::ExecutionContext execution_context{&dba, symbol_table,
|
||||
evaluation_context};
|
||||
TMemory memory;
|
||||
query::Frame frame(symbol_table.max_position(), memory.get());
|
||||
@ -158,23 +164,24 @@ template <class TMemory>
|
||||
static void ExpandVariable(benchmark::State &state) {
|
||||
query::AstStorage ast;
|
||||
query::Parameters parameters;
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
AddStarGraph(&db, state.range(0), state.range(1));
|
||||
query::SymbolTable symbol_table;
|
||||
auto expand_variable =
|
||||
MakeExpandVariable(query::EdgeAtom::Type::DEPTH_FIRST, &symbol_table);
|
||||
auto dba = db.Access();
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
// We need to only set the memory for temporary (per pull) evaluations
|
||||
TMemory per_pull_memory;
|
||||
query::EvaluationContext evaluation_context{per_pull_memory.get()};
|
||||
while (state.KeepRunning()) {
|
||||
query::DbAccessor execution_dba(&dba);
|
||||
query::ExecutionContext execution_context{&execution_dba, symbol_table,
|
||||
query::ExecutionContext execution_context{&dba, symbol_table,
|
||||
evaluation_context};
|
||||
TMemory memory;
|
||||
query::Frame frame(symbol_table.max_position(), memory.get());
|
||||
auto cursor = expand_variable.MakeCursor(memory.get());
|
||||
for (const auto &v : dba.Vertices(dba.Label(kStartLabel), false)) {
|
||||
for (const auto &v :
|
||||
dba.Vertices(storage::View::OLD, dba.NameToLabel(kStartLabel))) {
|
||||
frame[expand_variable.input_symbol_] =
|
||||
query::TypedValue(query::VertexAccessor(v));
|
||||
while (cursor->Pull(frame, execution_context)) per_pull_memory.Reset();
|
||||
@ -200,23 +207,24 @@ template <class TMemory>
|
||||
static void ExpandBfs(benchmark::State &state) {
|
||||
query::AstStorage ast;
|
||||
query::Parameters parameters;
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
AddTree(&db, state.range(0));
|
||||
query::SymbolTable symbol_table;
|
||||
auto expand_variable =
|
||||
MakeExpandVariable(query::EdgeAtom::Type::BREADTH_FIRST, &symbol_table);
|
||||
auto dba = db.Access();
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
// We need to only set the memory for temporary (per pull) evaluations
|
||||
TMemory per_pull_memory;
|
||||
query::EvaluationContext evaluation_context{per_pull_memory.get()};
|
||||
while (state.KeepRunning()) {
|
||||
query::DbAccessor execution_dba(&dba);
|
||||
query::ExecutionContext execution_context{&execution_dba, symbol_table,
|
||||
query::ExecutionContext execution_context{&dba, symbol_table,
|
||||
evaluation_context};
|
||||
TMemory memory;
|
||||
query::Frame frame(symbol_table.max_position(), memory.get());
|
||||
auto cursor = expand_variable.MakeCursor(memory.get());
|
||||
for (const auto &v : dba.Vertices(dba.Label(kStartLabel), false)) {
|
||||
for (const auto &v :
|
||||
dba.Vertices(storage::View::OLD, dba.NameToLabel(kStartLabel))) {
|
||||
frame[expand_variable.input_symbol_] =
|
||||
query::TypedValue(query::VertexAccessor(v));
|
||||
while (cursor->Pull(frame, execution_context)) per_pull_memory.Reset();
|
||||
@ -242,28 +250,30 @@ template <class TMemory>
|
||||
static void ExpandShortest(benchmark::State &state) {
|
||||
query::AstStorage ast;
|
||||
query::Parameters parameters;
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
AddTree(&db, state.range(0));
|
||||
query::SymbolTable symbol_table;
|
||||
auto expand_variable =
|
||||
MakeExpandVariable(query::EdgeAtom::Type::BREADTH_FIRST, &symbol_table);
|
||||
expand_variable.common_.existing_node = true;
|
||||
auto dest_symbol = expand_variable.common_.node_symbol;
|
||||
auto dba = db.Access();
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
// We need to only set the memory for temporary (per pull) evaluations
|
||||
TMemory per_pull_memory;
|
||||
query::EvaluationContext evaluation_context{per_pull_memory.get()};
|
||||
while (state.KeepRunning()) {
|
||||
query::DbAccessor execution_dba(&dba);
|
||||
query::ExecutionContext execution_context{&execution_dba, symbol_table,
|
||||
query::ExecutionContext execution_context{&dba, symbol_table,
|
||||
evaluation_context};
|
||||
TMemory memory;
|
||||
query::Frame frame(symbol_table.max_position(), memory.get());
|
||||
auto cursor = expand_variable.MakeCursor(memory.get());
|
||||
for (const auto &v : dba.Vertices(dba.Label(kStartLabel), false)) {
|
||||
for (const auto &v :
|
||||
dba.Vertices(storage::View::OLD, dba.NameToLabel(kStartLabel))) {
|
||||
frame[expand_variable.input_symbol_] =
|
||||
query::TypedValue(query::VertexAccessor(v));
|
||||
for (const auto &dest : dba.Vertices(false)) {
|
||||
for (const auto &dest :
|
||||
dba.Vertices(storage::View::OLD, dba.NameToLabel(kStartLabel))) {
|
||||
frame[dest_symbol] = query::TypedValue(query::VertexAccessor(dest));
|
||||
while (cursor->Pull(frame, execution_context)) per_pull_memory.Reset();
|
||||
}
|
||||
@ -289,7 +299,7 @@ template <class TMemory>
|
||||
static void ExpandWeightedShortest(benchmark::State &state) {
|
||||
query::AstStorage ast;
|
||||
query::Parameters parameters;
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
AddTree(&db, state.range(0));
|
||||
query::SymbolTable symbol_table;
|
||||
auto expand_variable = MakeExpandVariable(
|
||||
@ -300,21 +310,23 @@ static void ExpandWeightedShortest(benchmark::State &state) {
|
||||
symbol_table.CreateSymbol("vertex", false),
|
||||
ast.Create<query::PrimitiveLiteral>(1)};
|
||||
auto dest_symbol = expand_variable.common_.node_symbol;
|
||||
auto dba = db.Access();
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
// We need to only set the memory for temporary (per pull) evaluations
|
||||
TMemory per_pull_memory;
|
||||
query::EvaluationContext evaluation_context{per_pull_memory.get()};
|
||||
while (state.KeepRunning()) {
|
||||
query::DbAccessor execution_dba(&dba);
|
||||
query::ExecutionContext execution_context{&execution_dba, symbol_table,
|
||||
query::ExecutionContext execution_context{&dba, symbol_table,
|
||||
evaluation_context};
|
||||
TMemory memory;
|
||||
query::Frame frame(symbol_table.max_position(), memory.get());
|
||||
auto cursor = expand_variable.MakeCursor(memory.get());
|
||||
for (const auto &v : dba.Vertices(dba.Label(kStartLabel), false)) {
|
||||
for (const auto &v :
|
||||
dba.Vertices(storage::View::OLD, dba.NameToLabel(kStartLabel))) {
|
||||
frame[expand_variable.input_symbol_] =
|
||||
query::TypedValue(query::VertexAccessor(v));
|
||||
for (const auto &dest : dba.Vertices(false)) {
|
||||
for (const auto &dest :
|
||||
dba.Vertices(storage::View::OLD, dba.NameToLabel(kStartLabel))) {
|
||||
frame[dest_symbol] = query::TypedValue(query::VertexAccessor(dest));
|
||||
while (cursor->Pull(frame, execution_context)) per_pull_memory.Reset();
|
||||
}
|
||||
@ -340,7 +352,7 @@ template <class TMemory>
|
||||
static void Accumulate(benchmark::State &state) {
|
||||
query::AstStorage ast;
|
||||
query::Parameters parameters;
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
AddVertices(&db, state.range(1));
|
||||
query::SymbolTable symbol_table;
|
||||
auto scan_all = std::make_shared<query::plan::ScanAll>(
|
||||
@ -352,13 +364,13 @@ static void Accumulate(benchmark::State &state) {
|
||||
}
|
||||
query::plan::Accumulate accumulate(scan_all, symbols,
|
||||
/* advance_command= */ false);
|
||||
auto dba = db.Access();
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
// We need to only set the memory for temporary (per pull) evaluations
|
||||
TMemory per_pull_memory;
|
||||
query::EvaluationContext evaluation_context{per_pull_memory.get()};
|
||||
while (state.KeepRunning()) {
|
||||
query::DbAccessor execution_dba(&dba);
|
||||
query::ExecutionContext execution_context{&execution_dba, symbol_table,
|
||||
query::ExecutionContext execution_context{&dba, symbol_table,
|
||||
evaluation_context};
|
||||
TMemory memory;
|
||||
query::Frame frame(symbol_table.max_position(), memory.get());
|
||||
@ -385,7 +397,7 @@ template <class TMemory>
|
||||
static void Aggregate(benchmark::State &state) {
|
||||
query::AstStorage ast;
|
||||
query::Parameters parameters;
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
AddVertices(&db, state.range(1));
|
||||
query::SymbolTable symbol_table;
|
||||
auto scan_all = std::make_shared<query::plan::ScanAll>(
|
||||
@ -406,13 +418,13 @@ static void Aggregate(benchmark::State &state) {
|
||||
symbol_table.CreateSymbol("out" + std::to_string(i), false)});
|
||||
}
|
||||
query::plan::Aggregate aggregate(scan_all, aggregations, group_by, symbols);
|
||||
auto dba = db.Access();
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
// We need to only set the memory for temporary (per pull) evaluations
|
||||
TMemory per_pull_memory;
|
||||
query::EvaluationContext evaluation_context{per_pull_memory.get()};
|
||||
while (state.KeepRunning()) {
|
||||
query::DbAccessor execution_dba(&dba);
|
||||
query::ExecutionContext execution_context{&execution_dba, symbol_table,
|
||||
query::ExecutionContext execution_context{&dba, symbol_table,
|
||||
evaluation_context};
|
||||
TMemory memory;
|
||||
query::Frame frame(symbol_table.max_position(), memory.get());
|
||||
@ -443,7 +455,7 @@ template <class TMemory>
|
||||
static void OrderBy(benchmark::State &state) {
|
||||
query::AstStorage ast;
|
||||
query::Parameters parameters;
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
AddVertices(&db, state.range(1));
|
||||
query::SymbolTable symbol_table;
|
||||
auto scan_all = std::make_shared<query::plan::ScanAll>(
|
||||
@ -461,13 +473,13 @@ static void OrderBy(benchmark::State &state) {
|
||||
ast.Create<query::PrimitiveLiteral>(rand_value)});
|
||||
}
|
||||
query::plan::OrderBy order_by(scan_all, sort_items, symbols);
|
||||
auto dba = db.Access();
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
// We need to only set the memory for temporary (per pull) evaluations
|
||||
TMemory per_pull_memory;
|
||||
query::EvaluationContext evaluation_context{per_pull_memory.get()};
|
||||
while (state.KeepRunning()) {
|
||||
query::DbAccessor execution_dba(&dba);
|
||||
query::ExecutionContext execution_context{&execution_dba, symbol_table,
|
||||
query::ExecutionContext execution_context{&dba, symbol_table,
|
||||
evaluation_context};
|
||||
TMemory memory;
|
||||
query::Frame frame(symbol_table.max_position(), memory.get());
|
||||
@ -494,7 +506,7 @@ template <class TMemory>
|
||||
static void Unwind(benchmark::State &state) {
|
||||
query::AstStorage ast;
|
||||
query::Parameters parameters;
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
AddVertices(&db, state.range(0));
|
||||
query::SymbolTable symbol_table;
|
||||
auto scan_all = std::make_shared<query::plan::ScanAll>(
|
||||
@ -503,13 +515,13 @@ static void Unwind(benchmark::State &state) {
|
||||
auto *list_expr = ast.Create<query::Identifier>("list")->MapTo(list_sym);
|
||||
auto out_sym = symbol_table.CreateSymbol("out", false);
|
||||
query::plan::Unwind unwind(scan_all, list_expr, out_sym);
|
||||
auto dba = db.Access();
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
// We need to only set the memory for temporary (per pull) evaluations
|
||||
TMemory per_pull_memory;
|
||||
query::EvaluationContext evaluation_context{per_pull_memory.get()};
|
||||
while (state.KeepRunning()) {
|
||||
query::DbAccessor execution_dba(&dba);
|
||||
query::ExecutionContext execution_context{&execution_dba, symbol_table,
|
||||
query::ExecutionContext execution_context{&dba, symbol_table,
|
||||
evaluation_context};
|
||||
TMemory memory;
|
||||
query::Frame frame(symbol_table.max_position(), memory.get());
|
||||
|
@ -2,12 +2,11 @@
|
||||
|
||||
#include <benchmark/benchmark_api.h>
|
||||
|
||||
#include "database/single_node/graph_db.hpp"
|
||||
#include "database/single_node/graph_db_accessor.hpp"
|
||||
#include "query/frontend/semantic/symbol_generator.hpp"
|
||||
#include "query/plan/cost_estimator.hpp"
|
||||
#include "query/plan/planner.hpp"
|
||||
#include "query/plan/vertex_count_cache.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
|
||||
// Add chained MATCH (node1) -- (node2), MATCH (node2) -- (node3) ... clauses.
|
||||
static query::CypherQuery *AddChainedMatches(int num_matches,
|
||||
@ -34,17 +33,17 @@ static query::CypherQuery *AddChainedMatches(int num_matches,
|
||||
}
|
||||
|
||||
static void BM_PlanChainedMatches(benchmark::State &state) {
|
||||
database::GraphDb db;
|
||||
auto dba = db.Access();
|
||||
storage::Storage db;
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
while (state.KeepRunning()) {
|
||||
state.PauseTiming();
|
||||
query::AstStorage storage;
|
||||
int num_matches = state.range(0);
|
||||
auto *query = AddChainedMatches(num_matches, storage);
|
||||
auto symbol_table = query::MakeSymbolTable(query);
|
||||
query::DbAccessor exec_dba(&dba);
|
||||
auto ctx = query::plan::MakePlanningContext(&storage, &symbol_table, query,
|
||||
&exec_dba);
|
||||
auto ctx =
|
||||
query::plan::MakePlanningContext(&storage, &symbol_table, query, &dba);
|
||||
state.ResumeTiming();
|
||||
auto query_parts =
|
||||
query::plan::CollectQueryParts(symbol_table, storage, query);
|
||||
@ -91,30 +90,31 @@ static query::CypherQuery *AddIndexedMatches(int num_matches,
|
||||
}
|
||||
|
||||
static auto CreateIndexedVertices(int index_count, int vertex_count,
|
||||
database::GraphDb &db) {
|
||||
auto label = db.Access().Label("label");
|
||||
auto prop = db.Access().Property("prop");
|
||||
db.Access().BuildIndex(label, prop);
|
||||
auto dba = db.Access();
|
||||
storage::Storage *db) {
|
||||
auto label = db->NameToLabel("label");
|
||||
auto prop = db->NameToProperty("prop");
|
||||
db->CreateIndex(label, prop);
|
||||
auto dba = db->Access();
|
||||
for (int vi = 0; vi < vertex_count; ++vi) {
|
||||
for (int index = 0; index < index_count; ++index) {
|
||||
auto vertex = dba.InsertVertex();
|
||||
vertex.add_label(label);
|
||||
vertex.PropsSet(prop, PropertyValue(index));
|
||||
auto vertex = dba.CreateVertex();
|
||||
CHECK(vertex.AddLabel(label).HasValue());
|
||||
CHECK(vertex.SetProperty(prop, PropertyValue(index)).HasValue());
|
||||
}
|
||||
}
|
||||
dba.Commit();
|
||||
CHECK(!dba.Commit().HasError());
|
||||
return std::make_pair("label", "prop");
|
||||
}
|
||||
|
||||
static void BM_PlanAndEstimateIndexedMatching(benchmark::State &state) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
std::string label;
|
||||
std::string prop;
|
||||
int index_count = state.range(0);
|
||||
int vertex_count = state.range(1);
|
||||
std::tie(label, prop) = CreateIndexedVertices(index_count, vertex_count, db);
|
||||
auto dba = db.Access();
|
||||
std::tie(label, prop) = CreateIndexedVertices(index_count, vertex_count, &db);
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
query::Parameters parameters;
|
||||
while (state.KeepRunning()) {
|
||||
state.PauseTiming();
|
||||
@ -122,9 +122,8 @@ static void BM_PlanAndEstimateIndexedMatching(benchmark::State &state) {
|
||||
auto *query = AddIndexedMatches(index_count, label, prop, storage);
|
||||
auto symbol_table = query::MakeSymbolTable(query);
|
||||
state.ResumeTiming();
|
||||
query::DbAccessor exec_dba(&dba);
|
||||
auto ctx = query::plan::MakePlanningContext(&storage, &symbol_table, query,
|
||||
&exec_dba);
|
||||
auto ctx =
|
||||
query::plan::MakePlanningContext(&storage, &symbol_table, query, &dba);
|
||||
auto query_parts =
|
||||
query::plan::CollectQueryParts(symbol_table, storage, query);
|
||||
if (query_parts.query_parts.size() == 0) {
|
||||
@ -141,15 +140,15 @@ static void BM_PlanAndEstimateIndexedMatching(benchmark::State &state) {
|
||||
|
||||
static void BM_PlanAndEstimateIndexedMatchingWithCachedCounts(
|
||||
benchmark::State &state) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
std::string label;
|
||||
std::string prop;
|
||||
int index_count = state.range(0);
|
||||
int vertex_count = state.range(1);
|
||||
std::tie(label, prop) = CreateIndexedVertices(index_count, vertex_count, db);
|
||||
auto dba = db.Access();
|
||||
query::DbAccessor exec_dba(&dba);
|
||||
auto vertex_counts = query::plan::MakeVertexCountCache(&exec_dba);
|
||||
std::tie(label, prop) = CreateIndexedVertices(index_count, vertex_count, &db);
|
||||
auto storage_dba = db.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
auto vertex_counts = query::plan::MakeVertexCountCache(&dba);
|
||||
query::Parameters parameters;
|
||||
while (state.KeepRunning()) {
|
||||
state.PauseTiming();
|
||||
|
@ -53,7 +53,7 @@ add_manual_test(expression_pretty_printer.cpp)
|
||||
target_link_libraries(${test_prefix}expression_pretty_printer mg-single-node kvstore_dummy_lib)
|
||||
|
||||
add_manual_test(single_query.cpp)
|
||||
target_link_libraries(${test_prefix}single_query mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}single_query mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_manual_test(sl_position_and_count.cpp)
|
||||
target_link_libraries(${test_prefix}sl_position_and_count mg-single-node kvstore_dummy_lib)
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "communication/result_stream_faker.hpp"
|
||||
#include "database/single_node/graph_db.hpp"
|
||||
#include "database/single_node/graph_db_accessor.hpp"
|
||||
#include "query/interpreter.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
@ -12,11 +11,11 @@ int main(int argc, char *argv[]) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
query::InterpreterContext interpreter_context{&db};
|
||||
query::Interpreter interpreter{&interpreter_context};
|
||||
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db);
|
||||
auto [header, _] = interpreter.Prepare(argv[1], {});
|
||||
stream.Header(header);
|
||||
auto summary = interpreter.PullAll(&stream);
|
||||
|
@ -19,7 +19,7 @@ function(add_unit_test test_cpp)
|
||||
endfunction(add_unit_test)
|
||||
|
||||
add_unit_test(bolt_encoder.cpp)
|
||||
target_link_libraries(${test_prefix}bolt_encoder mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}bolt_encoder mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(commit_log_v2.cpp)
|
||||
target_link_libraries(${test_prefix}commit_log_v2 glog gflags)
|
||||
@ -34,7 +34,7 @@ add_unit_test(concurrent_map.cpp)
|
||||
target_link_libraries(${test_prefix}concurrent_map mg-single-node kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(cypher_main_visitor.cpp)
|
||||
target_link_libraries(${test_prefix}cypher_main_visitor mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}cypher_main_visitor mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(database_key_index.cpp)
|
||||
target_link_libraries(${test_prefix}database_key_index mg-single-node kvstore_dummy_lib)
|
||||
@ -73,7 +73,7 @@ add_unit_test(graph_db.cpp)
|
||||
target_link_libraries(${test_prefix}graph_db mg-single-node kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(interpreter.cpp)
|
||||
target_link_libraries(${test_prefix}interpreter mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}interpreter mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(kvstore.cpp)
|
||||
target_link_libraries(${test_prefix}kvstore kvstore_lib glog)
|
||||
@ -106,22 +106,22 @@ add_unit_test(replication_log.cpp)
|
||||
target_link_libraries(${test_prefix}replication_log mg-single-node-ha kvstore_lib glog)
|
||||
|
||||
add_unit_test(query_cost_estimator.cpp)
|
||||
target_link_libraries(${test_prefix}query_cost_estimator mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}query_cost_estimator mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(query_expression_evaluator.cpp)
|
||||
target_link_libraries(${test_prefix}query_expression_evaluator mg-single-node kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(plan_pretty_print.cpp)
|
||||
target_link_libraries(${test_prefix}plan_pretty_print mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}plan_pretty_print mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(query_dump.cpp)
|
||||
target_link_libraries(${test_prefix}query_dump mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}query_dump mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(query_pretty_print.cpp)
|
||||
target_link_libraries(${test_prefix}query_pretty_print mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}query_pretty_print mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(query_profile.cpp)
|
||||
target_link_libraries(${test_prefix}query_profile mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}query_profile mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(query_plan_accumulate_aggregate.cpp)
|
||||
target_link_libraries(${test_prefix}query_plan_accumulate_aggregate mg-single-node kvstore_dummy_lib)
|
||||
@ -138,13 +138,13 @@ target_link_libraries(${test_prefix}query_plan_v2_create_set_remove_delete mg-si
|
||||
# END Storage V2 in query execution
|
||||
|
||||
add_unit_test(query_plan_edge_cases.cpp)
|
||||
target_link_libraries(${test_prefix}query_plan_edge_cases mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}query_plan_edge_cases mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(query_plan_match_filter_return.cpp)
|
||||
target_link_libraries(${test_prefix}query_plan_match_filter_return mg-single-node kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(query_plan.cpp)
|
||||
target_link_libraries(${test_prefix}query_plan mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}query_plan mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
# Test query/procedure
|
||||
add_unit_test(query_procedure_mgp_type.cpp)
|
||||
@ -157,10 +157,10 @@ target_include_directories(${test_prefix}query_procedure_mgp_module PRIVATE ${CM
|
||||
# END query/procedure
|
||||
|
||||
add_unit_test(query_required_privileges.cpp)
|
||||
target_link_libraries(${test_prefix}query_required_privileges mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}query_required_privileges mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(query_semantic.cpp)
|
||||
target_link_libraries(${test_prefix}query_semantic mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}query_semantic mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(query_variable_start_planner.cpp)
|
||||
target_link_libraries(${test_prefix}query_variable_start_planner mg-single-node kvstore_dummy_lib)
|
||||
@ -212,13 +212,13 @@ add_unit_test(storage_stat.cpp)
|
||||
target_link_libraries(${test_prefix}storage_stat mg-single-node kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(stripped.cpp)
|
||||
target_link_libraries(${test_prefix}stripped mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}stripped mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(transaction_engine_single_node.cpp)
|
||||
target_link_libraries(${test_prefix}transaction_engine_single_node mg-single-node kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(typed_value.cpp)
|
||||
target_link_libraries(${test_prefix}typed_value mg-single-node kvstore_dummy_lib)
|
||||
target_link_libraries(${test_prefix}typed_value mg-single-node-v2 mg-auth kvstore_dummy_lib)
|
||||
|
||||
add_unit_test(unique_constraints.cpp)
|
||||
target_link_libraries(${test_prefix}unique_constraints mg-single-node kvstore_dummy_lib)
|
||||
|
@ -2,9 +2,8 @@
|
||||
#include "bolt_testdata.hpp"
|
||||
|
||||
#include "communication/bolt/v1/encoder/encoder.hpp"
|
||||
#include "database/single_node/graph_db.hpp"
|
||||
#include "database/single_node/graph_db_accessor.hpp"
|
||||
#include "glue/communication.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
|
||||
using communication::bolt::Value;
|
||||
|
||||
@ -164,50 +163,50 @@ TEST(BoltEncoder, VertexAndEdge) {
|
||||
output.clear();
|
||||
|
||||
// create vertex
|
||||
database::GraphDb db;
|
||||
auto db_accessor = db.Access();
|
||||
auto va1 = db_accessor.InsertVertex();
|
||||
auto va2 = db_accessor.InsertVertex();
|
||||
auto l1 = db_accessor.Label("label1");
|
||||
auto l2 = db_accessor.Label("label2");
|
||||
va1.add_label(l1);
|
||||
va1.add_label(l2);
|
||||
auto p1 = db_accessor.Property("prop1");
|
||||
auto p2 = db_accessor.Property("prop2");
|
||||
storage::Storage db;
|
||||
auto dba = db.Access();
|
||||
auto va1 = dba.CreateVertex();
|
||||
auto va2 = dba.CreateVertex();
|
||||
auto l1 = dba.NameToLabel("label1");
|
||||
auto l2 = dba.NameToLabel("label2");
|
||||
ASSERT_TRUE(va1.AddLabel(l1).HasValue());
|
||||
ASSERT_TRUE(va1.AddLabel(l2).HasValue());
|
||||
auto p1 = dba.NameToProperty("prop1");
|
||||
auto p2 = dba.NameToProperty("prop2");
|
||||
PropertyValue pv1(12), pv2(200);
|
||||
va1.PropsSet(p1, pv1);
|
||||
va1.PropsSet(p2, pv2);
|
||||
ASSERT_TRUE(va1.SetProperty(p1, pv1).HasValue());
|
||||
ASSERT_TRUE(va1.SetProperty(p2, pv2).HasValue());
|
||||
|
||||
// create edge
|
||||
auto et = db_accessor.EdgeType("edgetype");
|
||||
auto ea = db_accessor.InsertEdge(va1, va2, et);
|
||||
auto p3 = db_accessor.Property("prop3");
|
||||
auto p4 = db_accessor.Property("prop4");
|
||||
auto et = dba.NameToEdgeType("edgetype");
|
||||
auto ea = dba.CreateEdge(&va1, &va2, et);
|
||||
auto p3 = dba.NameToProperty("prop3");
|
||||
auto p4 = dba.NameToProperty("prop4");
|
||||
PropertyValue pv3(42), pv4(1234);
|
||||
ea.PropsSet(p3, pv3);
|
||||
ea.PropsSet(p4, pv4);
|
||||
ASSERT_TRUE(ea->SetProperty(p3, pv3).HasValue());
|
||||
ASSERT_TRUE(ea->SetProperty(p4, pv4).HasValue());
|
||||
|
||||
// check everything
|
||||
std::vector<Value> vals;
|
||||
vals.push_back(glue::ToBoltValue(
|
||||
query::TypedValue(query::VertexAccessor(va1)), storage::View::NEW));
|
||||
vals.push_back(glue::ToBoltValue(
|
||||
query::TypedValue(query::VertexAccessor(va2)), storage::View::NEW));
|
||||
vals.push_back(glue::ToBoltValue(query::TypedValue(query::EdgeAccessor(ea)),
|
||||
storage::View::NEW));
|
||||
vals.push_back(*glue::ToBoltValue(
|
||||
query::TypedValue(query::VertexAccessor(va1)), db, storage::View::NEW));
|
||||
vals.push_back(*glue::ToBoltValue(
|
||||
query::TypedValue(query::VertexAccessor(va2)), db, storage::View::NEW));
|
||||
vals.push_back(*glue::ToBoltValue(query::TypedValue(query::EdgeAccessor(*ea)),
|
||||
db, storage::View::NEW));
|
||||
bolt_encoder.MessageRecord(vals);
|
||||
|
||||
// The vertexedge_encoded testdata has hardcoded zeros for IDs,
|
||||
// and Memgraph now encodes IDs so we need to check the output
|
||||
// part by part.
|
||||
CheckOutput(output, vertexedge_encoded, 5, false);
|
||||
CheckInt(output, va1.gid().AsInt());
|
||||
CheckInt(output, va1.Gid().AsInt());
|
||||
CheckOutput(output, vertexedge_encoded + 6, 34, false);
|
||||
CheckInt(output, va2.gid().AsInt());
|
||||
CheckInt(output, va2.Gid().AsInt());
|
||||
CheckOutput(output, vertexedge_encoded + 41, 4, false);
|
||||
CheckInt(output, ea.gid().AsInt());
|
||||
CheckInt(output, va1.gid().AsInt());
|
||||
CheckInt(output, va2.gid().AsInt());
|
||||
CheckInt(output, ea->Gid().AsInt());
|
||||
CheckInt(output, va1.Gid().AsInt());
|
||||
CheckInt(output, va2.Gid().AsInt());
|
||||
CheckOutput(output, vertexedge_encoded + 48, 26);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <glog/logging.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "communication/result_stream_faker.hpp"
|
||||
#include "query/exceptions.hpp"
|
||||
#include "query/interpreter.hpp"
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#include "communication/bolt/v1/value.hpp"
|
||||
#include "communication/result_stream_faker.hpp"
|
||||
#include "database/single_node/graph_db_accessor.hpp"
|
||||
#include "glue/communication.hpp"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
@ -28,7 +27,7 @@ auto ToEdgeList(const communication::bolt::Value &v) {
|
||||
|
||||
class InterpreterTest : public ::testing::Test {
|
||||
protected:
|
||||
database::GraphDb db_;
|
||||
storage::Storage db_;
|
||||
query::InterpreterContext interpreter_context_{&db_};
|
||||
query::Interpreter interpreter_{&interpreter_context_};
|
||||
|
||||
@ -39,7 +38,7 @@ class InterpreterTest : public ::testing::Test {
|
||||
*/
|
||||
auto Interpret(const std::string &query,
|
||||
const std::map<std::string, PropertyValue> ¶ms = {}) {
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db_);
|
||||
|
||||
auto [header, _] = interpreter_.Prepare(query, params);
|
||||
stream.Header(header);
|
||||
@ -169,24 +168,29 @@ TEST_F(InterpreterTest, Bfs) {
|
||||
const auto kReachable = "reachable";
|
||||
const auto kId = "id";
|
||||
|
||||
std::vector<std::vector<VertexAccessor>> levels(kNumLevels);
|
||||
std::vector<std::vector<query::VertexAccessor>> levels(kNumLevels);
|
||||
int id = 0;
|
||||
|
||||
// Set up.
|
||||
{
|
||||
auto dba = db_.Access();
|
||||
auto storage_dba = db_.Access();
|
||||
query::DbAccessor dba(&storage_dba);
|
||||
auto add_node = [&](int level, bool reachable) {
|
||||
auto node = dba.InsertVertex();
|
||||
node.PropsSet(dba.Property(kId), PropertyValue(id++));
|
||||
node.PropsSet(dba.Property(kReachable), PropertyValue(reachable));
|
||||
CHECK(node.SetProperty(dba.NameToProperty(kId), PropertyValue(id++))
|
||||
.HasValue());
|
||||
CHECK(node.SetProperty(dba.NameToProperty(kReachable),
|
||||
PropertyValue(reachable))
|
||||
.HasValue());
|
||||
levels[level].push_back(node);
|
||||
return node;
|
||||
};
|
||||
|
||||
auto add_edge = [&](VertexAccessor &v1, VertexAccessor &v2,
|
||||
bool reachable) {
|
||||
auto edge = dba.InsertEdge(v1, v2, dba.EdgeType("edge"));
|
||||
edge.PropsSet(dba.Property(kReachable), PropertyValue(reachable));
|
||||
auto add_edge = [&](auto &v1, auto &v2, bool reachable) {
|
||||
auto edge = dba.InsertEdge(&v1, &v2, dba.NameToEdgeType("edge"));
|
||||
CHECK(edge->SetProperty(dba.NameToProperty(kReachable),
|
||||
PropertyValue(reachable))
|
||||
.HasValue());
|
||||
};
|
||||
|
||||
// Add source node.
|
||||
@ -224,7 +228,7 @@ TEST_F(InterpreterTest, Bfs) {
|
||||
add_edge(node1, node2, false);
|
||||
}
|
||||
|
||||
dba.Commit();
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
|
||||
auto stream = Interpret(
|
||||
@ -318,16 +322,15 @@ TEST_F(InterpreterTest, ShortestPath) {
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST_F(InterpreterTest, UniqueConstraintTest) {
|
||||
Interpret("CREATE CONSTRAINT ON (n:A) ASSERT n.a, n.b IS UNIQUE;");
|
||||
Interpret("CREATE (:A{a:1, b:1})");
|
||||
Interpret("CREATE (:A{a:2, b:2})");
|
||||
ASSERT_THROW(Interpret("CREATE (:A{a:1, b:1})"),
|
||||
query::QueryRuntimeException);
|
||||
Interpret("MATCH (n:A{a:2, b:2}) SET n.a=1");
|
||||
Interpret("CREATE (:A{a:2, b:2})");
|
||||
Interpret("MATCH (n:A{a:2, b:2}) DETACH DELETE n");
|
||||
Interpret("CREATE (n:A{a:2, b:2})");
|
||||
TEST_F(InterpreterTest, ExistenceConstraintTest) {
|
||||
Interpret("CREATE CONSTRAINT ON (n:A) ASSERT EXISTS (n.a);");
|
||||
Interpret("CREATE (:A{a:1})");
|
||||
Interpret("CREATE (:A{a:2})");
|
||||
ASSERT_THROW(Interpret("CREATE (:A)"), query::QueryException);
|
||||
Interpret("MATCH (n:A{a:2}) SET n.a=3");
|
||||
Interpret("CREATE (:A{a:2})");
|
||||
Interpret("MATCH (n:A{a:2}) DETACH DELETE n");
|
||||
Interpret("CREATE (n:A{a:2})");
|
||||
}
|
||||
|
||||
TEST_F(InterpreterTest, ExplainQuery) {
|
||||
|
@ -31,8 +31,8 @@ class PrintToJsonTest : public ::testing::Test {
|
||||
AstStorage storage;
|
||||
SymbolTable symbol_table;
|
||||
|
||||
database::GraphDb db;
|
||||
database::GraphDbAccessor dba;
|
||||
storage::Storage db;
|
||||
storage::Storage::Accessor dba;
|
||||
|
||||
Symbol GetSymbol(std::string name) {
|
||||
return symbol_table.CreateSymbol(name, true);
|
||||
@ -69,7 +69,7 @@ TEST_F(PrintToJsonTest, ScanAll) {
|
||||
TEST_F(PrintToJsonTest, ScanAllByLabel) {
|
||||
std::shared_ptr<LogicalOperator> last_op;
|
||||
last_op = std::make_shared<ScanAllByLabel>(nullptr, GetSymbol("node"),
|
||||
dba.Label("Label"));
|
||||
dba.NameToLabel("Label"));
|
||||
|
||||
Check(last_op.get(), R"(
|
||||
{
|
||||
@ -84,8 +84,9 @@ TEST_F(PrintToJsonTest, ScanAllByLabelPropertyRange) {
|
||||
{
|
||||
std::shared_ptr<LogicalOperator> last_op;
|
||||
last_op = std::make_shared<ScanAllByLabelPropertyRange>(
|
||||
nullptr, GetSymbol("node"), dba.Label("Label"), dba.Property("prop"),
|
||||
"prop", utils::MakeBoundInclusive<Expression *>(LITERAL(1)),
|
||||
nullptr, GetSymbol("node"), dba.NameToLabel("Label"),
|
||||
dba.NameToProperty("prop"), "prop",
|
||||
utils::MakeBoundInclusive<Expression *>(LITERAL(1)),
|
||||
utils::MakeBoundExclusive<Expression *>(LITERAL(20)));
|
||||
|
||||
Check(last_op.get(), R"(
|
||||
@ -108,8 +109,8 @@ TEST_F(PrintToJsonTest, ScanAllByLabelPropertyRange) {
|
||||
{
|
||||
std::shared_ptr<LogicalOperator> last_op;
|
||||
last_op = std::make_shared<ScanAllByLabelPropertyRange>(
|
||||
nullptr, GetSymbol("node"), dba.Label("Label"), dba.Property("prop"),
|
||||
"prop", std::nullopt,
|
||||
nullptr, GetSymbol("node"), dba.NameToLabel("Label"),
|
||||
dba.NameToProperty("prop"), "prop", std::nullopt,
|
||||
utils::MakeBoundExclusive<Expression *>(LITERAL(20)));
|
||||
|
||||
Check(last_op.get(), R"(
|
||||
@ -129,9 +130,9 @@ TEST_F(PrintToJsonTest, ScanAllByLabelPropertyRange) {
|
||||
{
|
||||
std::shared_ptr<LogicalOperator> last_op;
|
||||
last_op = std::make_shared<ScanAllByLabelPropertyRange>(
|
||||
nullptr, GetSymbol("node"), dba.Label("Label"), dba.Property("prop"),
|
||||
"prop", utils::MakeBoundInclusive<Expression *>(LITERAL(1)),
|
||||
std::nullopt);
|
||||
nullptr, GetSymbol("node"), dba.NameToLabel("Label"),
|
||||
dba.NameToProperty("prop"), "prop",
|
||||
utils::MakeBoundInclusive<Expression *>(LITERAL(1)), std::nullopt);
|
||||
|
||||
Check(last_op.get(), R"(
|
||||
{
|
||||
@ -152,8 +153,8 @@ TEST_F(PrintToJsonTest, ScanAllByLabelPropertyRange) {
|
||||
TEST_F(PrintToJsonTest, ScanAllByLabelPropertyValue) {
|
||||
std::shared_ptr<LogicalOperator> last_op;
|
||||
last_op = std::make_shared<ScanAllByLabelPropertyValue>(
|
||||
nullptr, GetSymbol("node"), dba.Label("Label"), dba.Property("prop"),
|
||||
"prop", ADD(LITERAL(21), LITERAL(21)));
|
||||
nullptr, GetSymbol("node"), dba.NameToLabel("Label"),
|
||||
dba.NameToProperty("prop"), "prop", ADD(LITERAL(21), LITERAL(21)));
|
||||
|
||||
Check(last_op.get(), R"sep(
|
||||
{
|
||||
@ -170,10 +171,11 @@ TEST_F(PrintToJsonTest, CreateNode) {
|
||||
std::shared_ptr<LogicalOperator> last_op;
|
||||
last_op = std::make_shared<CreateNode>(
|
||||
nullptr,
|
||||
NodeCreationInfo{GetSymbol("node"),
|
||||
{dba.Label("Label1"), dba.Label("Label2")},
|
||||
{{dba.Property("prop1"), LITERAL(5)},
|
||||
{dba.Property("prop2"), LITERAL("some cool stuff")}}});
|
||||
NodeCreationInfo{
|
||||
GetSymbol("node"),
|
||||
{dba.NameToLabel("Label1"), dba.NameToLabel("Label2")},
|
||||
{{dba.NameToProperty("prop1"), LITERAL(5)},
|
||||
{dba.NameToProperty("prop2"), LITERAL("some cool stuff")}}});
|
||||
|
||||
Check(last_op.get(), R"(
|
||||
{
|
||||
@ -195,13 +197,14 @@ TEST_F(PrintToJsonTest, CreateExpand) {
|
||||
std::shared_ptr<LogicalOperator> last_op =
|
||||
std::make_shared<ScanAll>(nullptr, GetSymbol("node1"));
|
||||
last_op = std::make_shared<CreateExpand>(
|
||||
NodeCreationInfo{GetSymbol("node2"),
|
||||
{dba.Label("Label1"), dba.Label("Label2")},
|
||||
{{dba.Property("prop1"), LITERAL(5)},
|
||||
{dba.Property("prop2"), LITERAL("some cool stuff")}}},
|
||||
NodeCreationInfo{
|
||||
GetSymbol("node2"),
|
||||
{dba.NameToLabel("Label1"), dba.NameToLabel("Label2")},
|
||||
{{dba.NameToProperty("prop1"), LITERAL(5)},
|
||||
{dba.NameToProperty("prop2"), LITERAL("some cool stuff")}}},
|
||||
EdgeCreationInfo{GetSymbol("edge"),
|
||||
{{dba.Property("weight"), LITERAL(5.32)}},
|
||||
dba.EdgeType("edge_type"),
|
||||
{{dba.NameToProperty("weight"), LITERAL(5.32)}},
|
||||
dba.NameToEdgeType("edge_type"),
|
||||
EdgeAtom::Direction::OUT},
|
||||
last_op, node1_sym, false);
|
||||
|
||||
@ -241,8 +244,8 @@ TEST_F(PrintToJsonTest, Expand) {
|
||||
last_op = std::make_shared<Expand>(
|
||||
last_op, node1_sym, GetSymbol("node2"), GetSymbol("edge"),
|
||||
EdgeAtom::Direction::BOTH,
|
||||
std::vector<storage::EdgeType>{dba.EdgeType("EdgeType1"),
|
||||
dba.EdgeType("EdgeType2")},
|
||||
std::vector<storage::EdgeTypeId>{dba.NameToEdgeType("EdgeType1"),
|
||||
dba.NameToEdgeType("EdgeType2")},
|
||||
false, storage::View::OLD);
|
||||
|
||||
Check(last_op.get(), R"(
|
||||
@ -269,11 +272,12 @@ TEST_F(PrintToJsonTest, ExpandVariable) {
|
||||
last_op = std::make_shared<ExpandVariable>(
|
||||
last_op, node1_sym, GetSymbol("node2"), GetSymbol("edge"),
|
||||
EdgeAtom::Type::BREADTH_FIRST, EdgeAtom::Direction::OUT,
|
||||
std::vector<storage::EdgeType>{dba.EdgeType("EdgeType1"),
|
||||
dba.EdgeType("EdgeType2")},
|
||||
std::vector<storage::EdgeTypeId>{dba.NameToEdgeType("EdgeType1"),
|
||||
dba.NameToEdgeType("EdgeType2")},
|
||||
false, LITERAL(2), LITERAL(5), false,
|
||||
ExpansionLambda{GetSymbol("inner_node"), GetSymbol("inner_edge"),
|
||||
PROPERTY_LOOKUP("inner_node", dba.Property("unblocked"))},
|
||||
ExpansionLambda{
|
||||
GetSymbol("inner_node"), GetSymbol("inner_edge"),
|
||||
PROPERTY_LOOKUP("inner_node", dba.NameToProperty("unblocked"))},
|
||||
std::nullopt, std::nullopt);
|
||||
|
||||
Check(last_op.get(), R"sep(
|
||||
@ -305,13 +309,14 @@ TEST_F(PrintToJsonTest, ExpandVariableWsp) {
|
||||
last_op = std::make_shared<ExpandVariable>(
|
||||
last_op, node1_sym, GetSymbol("node2"), GetSymbol("edge"),
|
||||
EdgeAtom::Type::WEIGHTED_SHORTEST_PATH, EdgeAtom::Direction::OUT,
|
||||
std::vector<storage::EdgeType>{dba.EdgeType("EdgeType1"),
|
||||
dba.EdgeType("EdgeType2")},
|
||||
std::vector<storage::EdgeTypeId>{dba.NameToEdgeType("EdgeType1"),
|
||||
dba.NameToEdgeType("EdgeType2")},
|
||||
false, LITERAL(2), LITERAL(5), false,
|
||||
ExpansionLambda{GetSymbol("inner_node"), GetSymbol("inner_edge"),
|
||||
nullptr},
|
||||
ExpansionLambda{GetSymbol("inner_node"), GetSymbol("inner_edge"),
|
||||
PROPERTY_LOOKUP("inner_edge", dba.Property("weight"))},
|
||||
ExpansionLambda{
|
||||
GetSymbol("inner_node"), GetSymbol("inner_edge"),
|
||||
PROPERTY_LOOKUP("inner_edge", dba.NameToProperty("weight"))},
|
||||
GetSymbol("total"));
|
||||
|
||||
Check(last_op.get(), R"sep(
|
||||
@ -349,10 +354,10 @@ TEST_F(PrintToJsonTest, ConstructNamedPath) {
|
||||
std::make_shared<ScanAll>(nullptr, node1_sym);
|
||||
last_op = std::make_shared<Expand>(
|
||||
last_op, node1_sym, node2_sym, edge1_sym, EdgeAtom::Direction::OUT,
|
||||
std::vector<storage::EdgeType>{}, false, storage::View::OLD);
|
||||
std::vector<storage::EdgeTypeId>{}, false, storage::View::OLD);
|
||||
last_op = std::make_shared<Expand>(
|
||||
last_op, node2_sym, node3_sym, edge2_sym, EdgeAtom::Direction::OUT,
|
||||
std::vector<storage::EdgeType>{}, false, storage::View::OLD);
|
||||
std::vector<storage::EdgeTypeId>{}, false, storage::View::OLD);
|
||||
last_op = std::make_shared<ConstructNamedPath>(
|
||||
last_op, GetSymbol("path"),
|
||||
std::vector<Symbol>{node1_sym, edge1_sym, node2_sym, edge2_sym,
|
||||
@ -393,7 +398,8 @@ TEST_F(PrintToJsonTest, Filter) {
|
||||
std::shared_ptr<LogicalOperator> last_op =
|
||||
std::make_shared<ScanAll>(nullptr, GetSymbol("node1"));
|
||||
last_op = std::make_shared<Filter>(
|
||||
last_op, EQ(PROPERTY_LOOKUP("node1", dba.Property("prop")), LITERAL(5)));
|
||||
last_op,
|
||||
EQ(PROPERTY_LOOKUP("node1", dba.NameToProperty("prop")), LITERAL(5)));
|
||||
|
||||
Check(last_op.get(), R"sep(
|
||||
{
|
||||
@ -436,7 +442,7 @@ TEST_F(PrintToJsonTest, Delete) {
|
||||
std::make_shared<ScanAll>(nullptr, node_sym);
|
||||
last_op = std::make_shared<Expand>(
|
||||
last_op, node_sym, GetSymbol("node2"), GetSymbol("edge"),
|
||||
EdgeAtom::Direction::BOTH, std::vector<storage::EdgeType>{}, false,
|
||||
EdgeAtom::Direction::BOTH, std::vector<storage::EdgeTypeId>{}, false,
|
||||
storage::View::OLD);
|
||||
last_op = std::make_shared<plan::Delete>(
|
||||
last_op, std::vector<Expression *>{IDENT("node2")}, true);
|
||||
@ -464,7 +470,7 @@ TEST_F(PrintToJsonTest, Delete) {
|
||||
}
|
||||
|
||||
TEST_F(PrintToJsonTest, SetProperty) {
|
||||
storage::Property prop = dba.Property("prop");
|
||||
storage::PropertyId prop = dba.NameToProperty("prop");
|
||||
|
||||
std::shared_ptr<LogicalOperator> last_op =
|
||||
std::make_shared<ScanAll>(nullptr, GetSymbol("node"));
|
||||
@ -516,7 +522,8 @@ TEST_F(PrintToJsonTest, SetLabels) {
|
||||
std::make_shared<ScanAll>(nullptr, node_sym);
|
||||
last_op = std::make_shared<plan::SetLabels>(
|
||||
last_op, node_sym,
|
||||
std::vector<storage::Label>{dba.Label("label1"), dba.Label("label2")});
|
||||
std::vector<storage::LabelId>{dba.NameToLabel("label1"),
|
||||
dba.NameToLabel("label2")});
|
||||
|
||||
Check(last_op.get(), R"(
|
||||
{
|
||||
@ -536,8 +543,8 @@ TEST_F(PrintToJsonTest, RemoveProperty) {
|
||||
std::shared_ptr<LogicalOperator> last_op =
|
||||
std::make_shared<ScanAll>(nullptr, node_sym);
|
||||
last_op = std::make_shared<plan::RemoveProperty>(
|
||||
last_op, dba.Property("prop"),
|
||||
PROPERTY_LOOKUP("node", dba.Property("prop")));
|
||||
last_op, dba.NameToProperty("prop"),
|
||||
PROPERTY_LOOKUP("node", dba.NameToProperty("prop")));
|
||||
|
||||
Check(last_op.get(), R"sep(
|
||||
{
|
||||
@ -558,7 +565,8 @@ TEST_F(PrintToJsonTest, RemoveLabels) {
|
||||
std::make_shared<ScanAll>(nullptr, node_sym);
|
||||
last_op = std::make_shared<plan::RemoveLabels>(
|
||||
last_op, node_sym,
|
||||
std::vector<storage::Label>{dba.Label("label1"), dba.Label("label2")});
|
||||
std::vector<storage::LabelId>{dba.NameToLabel("label1"),
|
||||
dba.NameToLabel("label2")});
|
||||
|
||||
Check(last_op.get(), R"(
|
||||
{
|
||||
@ -586,11 +594,11 @@ TEST_F(PrintToJsonTest, EdgeUniquenessFilter) {
|
||||
std::make_shared<ScanAll>(nullptr, node1_sym);
|
||||
last_op = std::make_shared<Expand>(
|
||||
last_op, node1_sym, node2_sym, edge1_sym, EdgeAtom::Direction::IN,
|
||||
std::vector<storage::EdgeType>{}, false, storage::View::OLD);
|
||||
std::vector<storage::EdgeTypeId>{}, false, storage::View::OLD);
|
||||
last_op = std::make_shared<ScanAll>(last_op, node3_sym);
|
||||
last_op = std::make_shared<Expand>(
|
||||
last_op, node3_sym, node4_sym, edge2_sym, EdgeAtom::Direction::OUT,
|
||||
std::vector<storage::EdgeType>{}, false, storage::View::OLD);
|
||||
std::vector<storage::EdgeTypeId>{}, false, storage::View::OLD);
|
||||
last_op = std::make_shared<EdgeUniquenessFilter>(
|
||||
last_op, edge2_sym, std::vector<Symbol>{edge1_sym});
|
||||
|
||||
@ -630,7 +638,7 @@ TEST_F(PrintToJsonTest, EdgeUniquenessFilter) {
|
||||
}
|
||||
|
||||
TEST_F(PrintToJsonTest, Accumulate) {
|
||||
storage::Property prop = dba.Property("prop");
|
||||
storage::PropertyId prop = dba.NameToProperty("prop");
|
||||
auto node_sym = GetSymbol("node");
|
||||
std::shared_ptr<LogicalOperator> last_op =
|
||||
std::make_shared<ScanAll>(nullptr, node_sym);
|
||||
@ -660,9 +668,9 @@ TEST_F(PrintToJsonTest, Accumulate) {
|
||||
}
|
||||
|
||||
TEST_F(PrintToJsonTest, Aggregate) {
|
||||
storage::Property value = dba.Property("value");
|
||||
storage::Property color = dba.Property("color");
|
||||
storage::Property type = dba.Property("type");
|
||||
storage::PropertyId value = dba.NameToProperty("value");
|
||||
storage::PropertyId color = dba.NameToProperty("color");
|
||||
storage::PropertyId type = dba.NameToProperty("type");
|
||||
auto node_sym = GetSymbol("node");
|
||||
std::shared_ptr<LogicalOperator> last_op =
|
||||
std::make_shared<ScanAll>(nullptr, node_sym);
|
||||
@ -745,8 +753,8 @@ TEST_F(PrintToJsonTest, Limit) {
|
||||
|
||||
TEST_F(PrintToJsonTest, OrderBy) {
|
||||
Symbol node_sym = GetSymbol("node");
|
||||
storage::Property value = dba.Property("value");
|
||||
storage::Property color = dba.Property("color");
|
||||
storage::PropertyId value = dba.NameToProperty("value");
|
||||
storage::PropertyId color = dba.NameToProperty("color");
|
||||
std::shared_ptr<LogicalOperator> last_op =
|
||||
std::make_shared<ScanAll>(nullptr, node_sym);
|
||||
last_op = std::make_shared<OrderBy>(
|
||||
@ -779,7 +787,7 @@ TEST_F(PrintToJsonTest, OrderBy) {
|
||||
|
||||
TEST_F(PrintToJsonTest, Merge) {
|
||||
Symbol node_sym = GetSymbol("node");
|
||||
storage::Label label = dba.Label("label");
|
||||
storage::LabelId label = dba.NameToLabel("label");
|
||||
|
||||
std::shared_ptr<LogicalOperator> match =
|
||||
std::make_shared<ScanAllByLabel>(nullptr, node_sym, label);
|
||||
@ -822,7 +830,7 @@ TEST_F(PrintToJsonTest, Optional) {
|
||||
|
||||
std::shared_ptr<LogicalOperator> expand = std::make_shared<Expand>(
|
||||
nullptr, node1_sym, node2_sym, edge_sym, EdgeAtom::Direction::OUT,
|
||||
std::vector<storage::EdgeType>{}, false, storage::View::OLD);
|
||||
std::vector<storage::EdgeTypeId>{}, false, storage::View::OLD);
|
||||
|
||||
std::shared_ptr<LogicalOperator> last_op = std::make_shared<Optional>(
|
||||
input, expand, std::vector<Symbol>{node2_sym, edge_sym});
|
||||
|
@ -32,9 +32,15 @@
|
||||
|
||||
#include "query/frontend/ast/ast.hpp"
|
||||
#include "query/frontend/ast/pretty_print.hpp"
|
||||
#include "storage/common/types/types.hpp"
|
||||
#include "utils/string.hpp"
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
#include "storage/v2/id_types.hpp"
|
||||
#else
|
||||
// TODO (mferencevic): Remove once all cpp tests are migrated to v2.
|
||||
#include "storage/common/types/types.hpp"
|
||||
#endif
|
||||
|
||||
namespace query {
|
||||
|
||||
namespace test_common {
|
||||
@ -115,6 +121,15 @@ auto GetOrderBy(T... exprs) {
|
||||
/// Create PropertyLookup with given name and property.
|
||||
///
|
||||
/// Name is used to create the Identifier which is used for property lookup.
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
template <class TDbAccessor>
|
||||
auto GetPropertyLookup(AstStorage &storage, TDbAccessor &dba,
|
||||
const std::string &name, storage::PropertyId property) {
|
||||
return storage.Create<PropertyLookup>(
|
||||
storage.Create<Identifier>(name),
|
||||
storage.GetPropertyIx(dba.PropertyToName(property)));
|
||||
}
|
||||
#else
|
||||
template <class TDbAccessor>
|
||||
auto GetPropertyLookup(AstStorage &storage, TDbAccessor &dba,
|
||||
const std::string &name, storage::Property property) {
|
||||
@ -122,13 +137,23 @@ auto GetPropertyLookup(AstStorage &storage, TDbAccessor &dba,
|
||||
storage.Create<Identifier>(name),
|
||||
storage.GetPropertyIx(dba.PropertyName(property)));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
template <class TDbAccessor>
|
||||
auto GetPropertyLookup(AstStorage &storage, TDbAccessor &dba, Expression *expr,
|
||||
storage::PropertyId property) {
|
||||
return storage.Create<PropertyLookup>(
|
||||
expr, storage.GetPropertyIx(dba.PropertyToName(property)));
|
||||
}
|
||||
#else
|
||||
template <class TDbAccessor>
|
||||
auto GetPropertyLookup(AstStorage &storage, TDbAccessor &dba, Expression *expr,
|
||||
storage::Property property) {
|
||||
return storage.Create<PropertyLookup>(
|
||||
expr, storage.GetPropertyIx(dba.PropertyName(property)));
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class TDbAccessor>
|
||||
auto GetPropertyLookup(AstStorage &storage, TDbAccessor &dba, Expression *expr,
|
||||
@ -139,7 +164,11 @@ auto GetPropertyLookup(AstStorage &storage, TDbAccessor &dba, Expression *expr,
|
||||
template <class TDbAccessor>
|
||||
auto GetPropertyLookup(
|
||||
AstStorage &storage, TDbAccessor &, const std::string &name,
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
const std::pair<std::string, storage::PropertyId> &prop_pair) {
|
||||
#else
|
||||
const std::pair<std::string, storage::Property> &prop_pair) {
|
||||
#endif
|
||||
return storage.Create<PropertyLookup>(storage.Create<Identifier>(name),
|
||||
storage.GetPropertyIx(prop_pair.first));
|
||||
}
|
||||
@ -147,7 +176,11 @@ auto GetPropertyLookup(
|
||||
template <class TDbAccessor>
|
||||
auto GetPropertyLookup(
|
||||
AstStorage &storage, TDbAccessor &, Expression *expr,
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
const std::pair<std::string, storage::PropertyId> &prop_pair) {
|
||||
#else
|
||||
const std::pair<std::string, storage::Property> &prop_pair) {
|
||||
#endif
|
||||
return storage.Create<PropertyLookup>(expr,
|
||||
storage.GetPropertyIx(prop_pair.first));
|
||||
}
|
||||
@ -539,8 +572,13 @@ auto GetMerge(AstStorage &storage, Pattern *pattern, OnMatch on_match,
|
||||
#define MAP(...) \
|
||||
storage.Create<query::MapLiteral>( \
|
||||
std::unordered_map<query::PropertyIx, query::Expression *>{__VA_ARGS__})
|
||||
#ifdef MG_SINGLE_NODE_V2
|
||||
#define PROPERTY_PAIR(property_name) \
|
||||
std::make_pair(property_name, dba.NameToProperty(property_name))
|
||||
#else
|
||||
#define PROPERTY_PAIR(property_name) \
|
||||
std::make_pair(property_name, dba.Property(property_name))
|
||||
#endif
|
||||
#define PROPERTY_LOOKUP(...) \
|
||||
query::test_common::GetPropertyLookup(storage, dba, __VA_ARGS__)
|
||||
#define PARAMETER_LOOKUP(token_position) \
|
||||
|
@ -1,20 +1,19 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <memory>
|
||||
|
||||
#include "database/single_node/graph_db.hpp"
|
||||
#include "database/single_node/graph_db_accessor.hpp"
|
||||
#include "query/db_accessor.hpp"
|
||||
#include "query/frontend/ast/ast.hpp"
|
||||
#include "query/frontend/semantic/symbol_table.hpp"
|
||||
#include "query/plan/cost_estimator.hpp"
|
||||
#include "query/plan/operator.hpp"
|
||||
#include "storage/vertex_accessor.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
|
||||
using namespace query;
|
||||
using namespace query::plan;
|
||||
|
||||
using CardParam = CostEstimator<database::GraphDbAccessor>::CardParam;
|
||||
using CostParam = CostEstimator<database::GraphDbAccessor>::CostParam;
|
||||
using MiscParam = CostEstimator<database::GraphDbAccessor>::MiscParam;
|
||||
using CardParam = CostEstimator<query::DbAccessor>::CardParam;
|
||||
using CostParam = CostEstimator<query::DbAccessor>::CostParam;
|
||||
using MiscParam = CostEstimator<query::DbAccessor>::MiscParam;
|
||||
|
||||
/** A fixture for cost estimation. Sets up the database
|
||||
* and accessor (adds some vertices). Provides convenience
|
||||
@ -23,10 +22,11 @@ using MiscParam = CostEstimator<database::GraphDbAccessor>::MiscParam;
|
||||
* estimation testing. */
|
||||
class QueryCostEstimator : public ::testing::Test {
|
||||
protected:
|
||||
database::GraphDb db;
|
||||
database::GraphDbAccessor dba{db.Access()};
|
||||
storage::Label label = dba.Label("label");
|
||||
storage::Property property = dba.Property("property");
|
||||
storage::Storage db;
|
||||
std::optional<storage::Storage::Accessor> storage_dba;
|
||||
std::optional<query::DbAccessor> dba;
|
||||
storage::LabelId label = db.NameToLabel("label");
|
||||
storage::PropertyId property = db.NameToProperty("property");
|
||||
|
||||
// we incrementally build the logical operator plan
|
||||
// start it off with Once
|
||||
@ -38,9 +38,10 @@ class QueryCostEstimator : public ::testing::Test {
|
||||
int symbol_count = 0;
|
||||
|
||||
void SetUp() {
|
||||
// create the index in the current db accessor and then swap it to a new one
|
||||
dba.BuildIndex(label, property);
|
||||
dba = db.Access();
|
||||
ASSERT_TRUE(db.CreateIndex(label));
|
||||
ASSERT_TRUE(db.CreateIndex(label, property));
|
||||
storage_dba.emplace(db.Access());
|
||||
dba.emplace(&*storage_dba);
|
||||
}
|
||||
|
||||
Symbol NextSymbol() {
|
||||
@ -53,16 +54,21 @@ class QueryCostEstimator : public ::testing::Test {
|
||||
void AddVertices(int vertex_count, int labeled_count,
|
||||
int property_count = 0) {
|
||||
for (int i = 0; i < vertex_count; i++) {
|
||||
auto vertex = dba.InsertVertex();
|
||||
if (i < labeled_count) vertex.add_label(label);
|
||||
if (i < property_count) vertex.PropsSet(property, PropertyValue(i));
|
||||
auto vertex = dba->InsertVertex();
|
||||
if (i < labeled_count) {
|
||||
ASSERT_TRUE(vertex.AddLabel(label).HasValue());
|
||||
}
|
||||
if (i < property_count) {
|
||||
ASSERT_TRUE(
|
||||
vertex.SetProperty(property, storage::PropertyValue(i)).HasValue());
|
||||
}
|
||||
}
|
||||
|
||||
dba.AdvanceCommand();
|
||||
dba->AdvanceCommand();
|
||||
}
|
||||
|
||||
auto Cost() {
|
||||
CostEstimator<database::GraphDbAccessor> cost_estimator(&dba, parameters_);
|
||||
CostEstimator<query::DbAccessor> cost_estimator(&*dba, parameters_);
|
||||
last_op_->Accept(cost_estimator);
|
||||
return cost_estimator.cost();
|
||||
}
|
||||
@ -166,7 +172,7 @@ TEST_F(QueryCostEstimator, ScanAllByLabelPropertyRangeConstExpr) {
|
||||
|
||||
TEST_F(QueryCostEstimator, Expand) {
|
||||
MakeOp<Expand>(last_op_, NextSymbol(), NextSymbol(), NextSymbol(),
|
||||
EdgeAtom::Direction::IN, std::vector<storage::EdgeType>{},
|
||||
EdgeAtom::Direction::IN, std::vector<storage::EdgeTypeId>{},
|
||||
false, storage::View::OLD);
|
||||
EXPECT_COST(CardParam::kExpand * CostParam::kExpand);
|
||||
}
|
||||
@ -174,7 +180,7 @@ TEST_F(QueryCostEstimator, Expand) {
|
||||
TEST_F(QueryCostEstimator, ExpandVariable) {
|
||||
MakeOp<ExpandVariable>(last_op_, NextSymbol(), NextSymbol(), NextSymbol(),
|
||||
EdgeAtom::Type::DEPTH_FIRST, EdgeAtom::Direction::IN,
|
||||
std::vector<storage::EdgeType>{}, false, nullptr,
|
||||
std::vector<storage::EdgeTypeId>{}, false, nullptr,
|
||||
nullptr, false,
|
||||
ExpansionLambda{NextSymbol(), NextSymbol(), nullptr},
|
||||
std::nullopt, std::nullopt);
|
||||
@ -197,9 +203,8 @@ TEST_F(QueryCostEstimator, Filter) {
|
||||
|
||||
TEST_F(QueryCostEstimator, EdgeUniquenessFilter) {
|
||||
TEST_OP(MakeOp<EdgeUniquenessFilter>(last_op_, NextSymbol(),
|
||||
std::vector<Symbol>()),
|
||||
CostParam::kEdgeUniquenessFilter,
|
||||
CardParam::kEdgeUniquenessFilter);
|
||||
std::vector<Symbol>()),
|
||||
CostParam::kEdgeUniquenessFilter, CardParam::kEdgeUniquenessFilter);
|
||||
}
|
||||
|
||||
TEST_F(QueryCostEstimator, UnwindLiteral) {
|
||||
|
@ -7,14 +7,10 @@
|
||||
#include <glog/logging.h>
|
||||
|
||||
#include "communication/result_stream_faker.hpp"
|
||||
#include "database/graph_db.hpp"
|
||||
#include "database/graph_db_accessor.hpp"
|
||||
#include "query/dump.hpp"
|
||||
#include "query/interpreter.hpp"
|
||||
#include "query/typed_value.hpp"
|
||||
#include "storage/common/types/property_value.hpp"
|
||||
|
||||
using database::GraphDbAccessor;
|
||||
#include "storage/v2/storage.hpp"
|
||||
|
||||
const char *kPropertyId = "property_id";
|
||||
|
||||
@ -40,20 +36,20 @@ struct DatabaseState {
|
||||
std::map<std::string, PropertyValue> props;
|
||||
};
|
||||
|
||||
struct IndexKey {
|
||||
struct LabelItem {
|
||||
std::string label;
|
||||
};
|
||||
|
||||
struct LabelPropertyItem {
|
||||
std::string label;
|
||||
std::string property;
|
||||
};
|
||||
|
||||
struct UniqueConstraint {
|
||||
std::string label;
|
||||
std::set<std::string> props;
|
||||
};
|
||||
|
||||
std::set<Vertex> vertices;
|
||||
std::set<Edge> edges;
|
||||
std::set<IndexKey> indices;
|
||||
std::set<UniqueConstraint> constraints;
|
||||
std::set<LabelItem> label_indices;
|
||||
std::set<LabelPropertyItem> label_property_indices;
|
||||
std::set<LabelPropertyItem> existence_constraints;
|
||||
};
|
||||
|
||||
bool operator<(const DatabaseState::Vertex &first,
|
||||
@ -72,16 +68,15 @@ bool operator<(const DatabaseState::Edge &first,
|
||||
return first.props < second.props;
|
||||
}
|
||||
|
||||
bool operator<(const DatabaseState::IndexKey &first,
|
||||
const DatabaseState::IndexKey &second) {
|
||||
if (first.label != second.label) return first.label < second.label;
|
||||
return first.property < second.property;
|
||||
bool operator<(const DatabaseState::LabelItem &first,
|
||||
const DatabaseState::LabelItem &second) {
|
||||
return first.label < second.label;
|
||||
}
|
||||
|
||||
bool operator<(const DatabaseState::UniqueConstraint &first,
|
||||
const DatabaseState::UniqueConstraint &second) {
|
||||
bool operator<(const DatabaseState::LabelPropertyItem &first,
|
||||
const DatabaseState::LabelPropertyItem &second) {
|
||||
if (first.label != second.label) return first.label < second.label;
|
||||
return first.props < second.props;
|
||||
return first.property < second.property;
|
||||
}
|
||||
|
||||
bool operator==(const DatabaseState::Vertex &first,
|
||||
@ -96,78 +91,98 @@ bool operator==(const DatabaseState::Edge &first,
|
||||
first.edge_type == second.edge_type && first.props == second.props;
|
||||
}
|
||||
|
||||
bool operator==(const DatabaseState::IndexKey &first,
|
||||
const DatabaseState::IndexKey &second) {
|
||||
return first.label == second.label && first.property == second.property;
|
||||
bool operator==(const DatabaseState::LabelItem &first,
|
||||
const DatabaseState::LabelItem &second) {
|
||||
return first.label == second.label;
|
||||
}
|
||||
|
||||
bool operator==(const DatabaseState::UniqueConstraint &first,
|
||||
const DatabaseState::UniqueConstraint &second) {
|
||||
return first.label == second.label && first.props == second.props;
|
||||
bool operator==(const DatabaseState::LabelPropertyItem &first,
|
||||
const DatabaseState::LabelPropertyItem &second) {
|
||||
return first.label == second.label && first.property == second.property;
|
||||
}
|
||||
|
||||
bool operator==(const DatabaseState &first, const DatabaseState &second) {
|
||||
return first.vertices == second.vertices && first.edges == second.edges &&
|
||||
first.indices == second.indices;
|
||||
first.label_indices == second.label_indices &&
|
||||
first.label_property_indices == second.label_property_indices &&
|
||||
first.existence_constraints == second.existence_constraints;
|
||||
}
|
||||
|
||||
DatabaseState GetState(database::GraphDb *db) {
|
||||
DatabaseState GetState(storage::Storage *db) {
|
||||
// Capture all vertices
|
||||
std::map<storage::Gid, int64_t> gid_mapping;
|
||||
std::set<DatabaseState::Vertex> vertices;
|
||||
auto dba = db->Access();
|
||||
for (const auto &vertex : dba.Vertices(false)) {
|
||||
for (const auto &vertex : dba.Vertices(storage::View::NEW)) {
|
||||
std::set<std::string> labels;
|
||||
for (const auto &label : vertex.labels()) {
|
||||
labels.insert(dba.LabelName(label));
|
||||
auto maybe_labels = vertex.Labels(storage::View::NEW);
|
||||
CHECK(maybe_labels.HasValue());
|
||||
for (const auto &label : *maybe_labels) {
|
||||
labels.insert(dba.LabelToName(label));
|
||||
}
|
||||
std::map<std::string, PropertyValue> props;
|
||||
for (const auto &kv : vertex.Properties()) {
|
||||
props.emplace(dba.PropertyName(kv.first), kv.second);
|
||||
auto maybe_properties = vertex.Properties(storage::View::NEW);
|
||||
CHECK(maybe_properties.HasValue());
|
||||
for (const auto &kv : *maybe_properties) {
|
||||
props.emplace(dba.PropertyToName(kv.first), kv.second);
|
||||
}
|
||||
CHECK(props.count(kPropertyId) == 1);
|
||||
const auto id = props[kPropertyId].ValueInt();
|
||||
gid_mapping[vertex.gid()] = id;
|
||||
gid_mapping[vertex.Gid()] = id;
|
||||
vertices.insert({id, labels, props});
|
||||
}
|
||||
|
||||
// Capture all edges
|
||||
std::set<DatabaseState::Edge> edges;
|
||||
for (const auto &edge : dba.Edges(false)) {
|
||||
const auto &edge_type_name = dba.EdgeTypeName(edge.EdgeType());
|
||||
std::map<std::string, PropertyValue> props;
|
||||
for (const auto &kv : edge.Properties()) {
|
||||
props.emplace(dba.PropertyName(kv.first), kv.second);
|
||||
for (const auto &vertex : dba.Vertices(storage::View::NEW)) {
|
||||
auto maybe_edges = vertex.OutEdges({}, storage::View::NEW);
|
||||
CHECK(maybe_edges.HasValue());
|
||||
for (const auto &edge : *maybe_edges) {
|
||||
const auto &edge_type_name = dba.EdgeTypeToName(edge.EdgeType());
|
||||
std::map<std::string, PropertyValue> props;
|
||||
auto maybe_properties = edge.Properties(storage::View::NEW);
|
||||
CHECK(maybe_properties.HasValue());
|
||||
for (const auto &kv : *maybe_properties) {
|
||||
props.emplace(dba.PropertyToName(kv.first), kv.second);
|
||||
}
|
||||
const auto from = gid_mapping[edge.FromVertex().Gid()];
|
||||
const auto to = gid_mapping[edge.ToVertex().Gid()];
|
||||
edges.insert({from, to, edge_type_name, props});
|
||||
}
|
||||
const auto from = gid_mapping[edge.from().gid()];
|
||||
const auto to = gid_mapping[edge.to().gid()];
|
||||
edges.insert({from, to, edge_type_name, props});
|
||||
}
|
||||
|
||||
// Capture all indices
|
||||
std::set<DatabaseState::IndexKey> indices;
|
||||
for (const auto &key : dba.GetIndicesKeys()) {
|
||||
indices.insert(
|
||||
{dba.LabelName(key.label_), dba.PropertyName(key.property_)});
|
||||
}
|
||||
|
||||
// Capture all unique constraints
|
||||
std::set<DatabaseState::UniqueConstraint> constraints;
|
||||
for (const auto &constraint : dba.ListUniqueConstraints()) {
|
||||
std::set<std::string> props;
|
||||
for (const auto &prop : constraint.properties) {
|
||||
props.insert(dba.PropertyName(prop));
|
||||
std::set<DatabaseState::LabelItem> label_indices;
|
||||
std::set<DatabaseState::LabelPropertyItem> label_property_indices;
|
||||
{
|
||||
auto info = dba.ListAllIndices();
|
||||
for (const auto &item : info.label) {
|
||||
label_indices.insert({dba.LabelToName(item)});
|
||||
}
|
||||
for (const auto &item : info.label_property) {
|
||||
label_property_indices.insert(
|
||||
{dba.LabelToName(item.first), dba.PropertyToName(item.second)});
|
||||
}
|
||||
constraints.insert({dba.LabelName(constraint.label), props});
|
||||
}
|
||||
|
||||
return {vertices, edges, indices, constraints};
|
||||
// Capture all constraints
|
||||
std::set<DatabaseState::LabelPropertyItem> existence_constraints;
|
||||
{
|
||||
auto info = dba.ListAllConstraints();
|
||||
for (const auto &item : info.existence) {
|
||||
existence_constraints.insert(
|
||||
{dba.LabelToName(item.first), dba.PropertyToName(item.second)});
|
||||
}
|
||||
}
|
||||
|
||||
return {vertices, edges, label_indices, label_property_indices,
|
||||
existence_constraints};
|
||||
}
|
||||
|
||||
auto Execute(database::GraphDb *db, const std::string &query) {
|
||||
auto Execute(storage::Storage *db, const std::string &query) {
|
||||
query::InterpreterContext context(db);
|
||||
query::Interpreter interpreter(&context);
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(db);
|
||||
|
||||
auto [header, _] = interpreter.Prepare(query, {});
|
||||
stream.Header(header);
|
||||
@ -177,39 +192,45 @@ auto Execute(database::GraphDb *db, const std::string &query) {
|
||||
return stream;
|
||||
}
|
||||
|
||||
VertexAccessor CreateVertex(GraphDbAccessor *dba,
|
||||
VertexAccessor CreateVertex(storage::Storage::Accessor *dba,
|
||||
const std::vector<std::string> &labels,
|
||||
const std::map<std::string, PropertyValue> &props,
|
||||
bool add_property_id = true) {
|
||||
CHECK(dba);
|
||||
auto vertex = dba->InsertVertex();
|
||||
auto vertex = dba->CreateVertex();
|
||||
for (const auto &label_name : labels) {
|
||||
vertex.add_label(dba->Label(label_name));
|
||||
CHECK(vertex.AddLabel(dba->NameToLabel(label_name)).HasValue());
|
||||
}
|
||||
for (const auto &kv : props) {
|
||||
vertex.PropsSet(dba->Property(kv.first), kv.second);
|
||||
CHECK(vertex.SetProperty(dba->NameToProperty(kv.first), kv.second)
|
||||
.HasValue());
|
||||
}
|
||||
if (add_property_id) {
|
||||
vertex.PropsSet(dba->Property(kPropertyId),
|
||||
PropertyValue(vertex.gid().AsInt()));
|
||||
CHECK(vertex
|
||||
.SetProperty(dba->NameToProperty(kPropertyId),
|
||||
PropertyValue(vertex.Gid().AsInt()))
|
||||
.HasValue());
|
||||
}
|
||||
return vertex;
|
||||
}
|
||||
|
||||
EdgeAccessor CreateEdge(GraphDbAccessor *dba, VertexAccessor from,
|
||||
VertexAccessor to, const std::string &edge_type_name,
|
||||
EdgeAccessor CreateEdge(storage::Storage::Accessor *dba, VertexAccessor *from,
|
||||
VertexAccessor *to, const std::string &edge_type_name,
|
||||
const std::map<std::string, PropertyValue> &props,
|
||||
bool add_property_id = true) {
|
||||
CHECK(dba);
|
||||
auto edge = dba->InsertEdge(from, to, dba->EdgeType(edge_type_name));
|
||||
auto edge = dba->CreateEdge(from, to, dba->NameToEdgeType(edge_type_name));
|
||||
CHECK(edge.HasValue());
|
||||
for (const auto &kv : props) {
|
||||
edge.PropsSet(dba->Property(kv.first), kv.second);
|
||||
CHECK(
|
||||
edge->SetProperty(dba->NameToProperty(kv.first), kv.second).HasValue());
|
||||
}
|
||||
if (add_property_id) {
|
||||
edge.PropsSet(dba->Property(kPropertyId),
|
||||
PropertyValue(edge.gid().AsInt()));
|
||||
CHECK(edge->SetProperty(dba->NameToProperty(kPropertyId),
|
||||
PropertyValue(edge->Gid().AsInt()))
|
||||
.HasValue());
|
||||
}
|
||||
return edge;
|
||||
return *edge;
|
||||
}
|
||||
|
||||
template <class... TArgs>
|
||||
@ -229,8 +250,8 @@ void VerifyQueries(
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, EmptyGraph) {
|
||||
database::GraphDb db;
|
||||
ResultStreamFaker stream;
|
||||
storage::Storage db;
|
||||
ResultStreamFaker stream(&db);
|
||||
query::AnyStream query_stream(&stream, utils::NewDeleteResource());
|
||||
{
|
||||
auto acc = db.Access();
|
||||
@ -242,15 +263,15 @@ TEST(DumpTest, EmptyGraph) {
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, SingleVertex) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
CreateVertex(&dba, {}, {}, false);
|
||||
dba.Commit();
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
|
||||
{
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db);
|
||||
query::AnyStream query_stream(&stream, utils::NewDeleteResource());
|
||||
{
|
||||
auto acc = db.Access();
|
||||
@ -265,15 +286,15 @@ TEST(DumpTest, SingleVertex) {
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, VertexWithSingleLabel) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
CreateVertex(&dba, {"Label1"}, {}, false);
|
||||
dba.Commit();
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
|
||||
{
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db);
|
||||
query::AnyStream query_stream(&stream, utils::NewDeleteResource());
|
||||
{
|
||||
auto acc = db.Access();
|
||||
@ -288,15 +309,15 @@ TEST(DumpTest, VertexWithSingleLabel) {
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, VertexWithMultipleLabels) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
CreateVertex(&dba, {"Label1", "Label2"}, {}, false);
|
||||
dba.Commit();
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
|
||||
{
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db);
|
||||
query::AnyStream query_stream(&stream, utils::NewDeleteResource());
|
||||
{
|
||||
auto acc = db.Access();
|
||||
@ -311,15 +332,15 @@ TEST(DumpTest, VertexWithMultipleLabels) {
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, VertexWithSingleProperty) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
CreateVertex(&dba, {}, {{"prop", PropertyValue(42)}}, false);
|
||||
dba.Commit();
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
|
||||
{
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db);
|
||||
query::AnyStream query_stream(&stream, utils::NewDeleteResource());
|
||||
{
|
||||
auto acc = db.Access();
|
||||
@ -334,17 +355,17 @@ TEST(DumpTest, VertexWithSingleProperty) {
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, MultipleVertices) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
CreateVertex(&dba, {}, {}, false);
|
||||
CreateVertex(&dba, {}, {}, false);
|
||||
CreateVertex(&dba, {}, {}, false);
|
||||
dba.Commit();
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
|
||||
{
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db);
|
||||
query::AnyStream query_stream(&stream, utils::NewDeleteResource());
|
||||
{
|
||||
auto acc = db.Access();
|
||||
@ -361,17 +382,17 @@ TEST(DumpTest, MultipleVertices) {
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, SingleEdge) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto u = CreateVertex(&dba, {}, {}, false);
|
||||
auto v = CreateVertex(&dba, {}, {}, false);
|
||||
CreateEdge(&dba, u, v, "EdgeType", {}, false);
|
||||
dba.Commit();
|
||||
CreateEdge(&dba, &u, &v, "EdgeType", {}, false);
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
|
||||
{
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db);
|
||||
query::AnyStream query_stream(&stream, utils::NewDeleteResource());
|
||||
{
|
||||
auto acc = db.Access();
|
||||
@ -390,20 +411,20 @@ TEST(DumpTest, SingleEdge) {
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, MultipleEdges) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto u = CreateVertex(&dba, {}, {}, false);
|
||||
auto v = CreateVertex(&dba, {}, {}, false);
|
||||
auto w = CreateVertex(&dba, {}, {}, false);
|
||||
CreateEdge(&dba, u, v, "EdgeType", {}, false);
|
||||
CreateEdge(&dba, v, u, "EdgeType", {}, false);
|
||||
CreateEdge(&dba, v, w, "EdgeType", {}, false);
|
||||
dba.Commit();
|
||||
CreateEdge(&dba, &u, &v, "EdgeType", {}, false);
|
||||
CreateEdge(&dba, &v, &u, "EdgeType", {}, false);
|
||||
CreateEdge(&dba, &v, &w, "EdgeType", {}, false);
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
|
||||
{
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db);
|
||||
query::AnyStream query_stream(&stream, utils::NewDeleteResource());
|
||||
{
|
||||
auto acc = db.Access();
|
||||
@ -427,17 +448,17 @@ TEST(DumpTest, MultipleEdges) {
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, EdgeWithProperties) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto u = CreateVertex(&dba, {}, {}, false);
|
||||
auto v = CreateVertex(&dba, {}, {}, false);
|
||||
CreateEdge(&dba, u, v, "EdgeType", {{"prop", PropertyValue(13)}}, false);
|
||||
dba.Commit();
|
||||
CreateEdge(&dba, &u, &v, "EdgeType", {{"prop", PropertyValue(13)}}, false);
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
|
||||
{
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db);
|
||||
query::AnyStream query_stream(&stream, utils::NewDeleteResource());
|
||||
{
|
||||
auto acc = db.Access();
|
||||
@ -456,17 +477,19 @@ TEST(DumpTest, EdgeWithProperties) {
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, IndicesKeys) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
CreateVertex(&dba, {"Label1", "Label2"}, {{"p", PropertyValue(1)}}, false);
|
||||
dba.BuildIndex(dba.Label("Label1"), dba.Property("prop"));
|
||||
dba.BuildIndex(dba.Label("Label2"), dba.Property("prop"));
|
||||
dba.Commit();
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
ASSERT_TRUE(
|
||||
db.CreateIndex(db.NameToLabel("Label1"), db.NameToProperty("prop")));
|
||||
ASSERT_TRUE(
|
||||
db.CreateIndex(db.NameToLabel("Label2"), db.NameToProperty("prop")));
|
||||
|
||||
{
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db);
|
||||
query::AnyStream query_stream(&stream, utils::NewDeleteResource());
|
||||
{
|
||||
auto acc = db.Access();
|
||||
@ -481,39 +504,39 @@ TEST(DumpTest, IndicesKeys) {
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, UniqueConstraints) {
|
||||
database::GraphDb db;
|
||||
TEST(DumpTest, ExistenceConstraints) {
|
||||
storage::Storage db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
CreateVertex(&dba, {"Label"}, {{"prop", PropertyValue(1)}}, false);
|
||||
dba.BuildUniqueConstraint(dba.Label("Label"), {dba.Property("prop")});
|
||||
// Create one with multiple properties.
|
||||
dba.BuildUniqueConstraint(dba.Label("Label"),
|
||||
{dba.Property("prop1"), dba.Property("prop2")});
|
||||
dba.Commit();
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
{
|
||||
auto res = db.CreateExistenceConstraint(db.NameToLabel("Label"),
|
||||
db.NameToProperty("prop"));
|
||||
ASSERT_TRUE(res.HasValue());
|
||||
ASSERT_TRUE(res.GetValue());
|
||||
}
|
||||
|
||||
{
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db);
|
||||
query::AnyStream query_stream(&stream, utils::NewDeleteResource());
|
||||
{
|
||||
auto acc = db.Access();
|
||||
query::DbAccessor dba(&acc);
|
||||
query::DumpDatabaseToCypherQueries(&dba, &query_stream);
|
||||
}
|
||||
VerifyQueries(
|
||||
stream.GetResults(),
|
||||
"CREATE CONSTRAINT ON (u:Label) ASSERT u.prop IS UNIQUE;",
|
||||
"CREATE CONSTRAINT ON (u:Label) ASSERT u.prop1, u.prop2 IS UNIQUE;",
|
||||
kCreateInternalIndex,
|
||||
"CREATE (:__mg_vertex__:Label {__mg_id__: 0, prop: 1});",
|
||||
kDropInternalIndex, kRemoveInternalLabelProperty);
|
||||
VerifyQueries(stream.GetResults(),
|
||||
"CREATE CONSTRAINT ON (u:Label) ASSERT EXISTS (u.prop);",
|
||||
kCreateInternalIndex,
|
||||
"CREATE (:__mg_vertex__:Label {__mg_id__: 0, prop: 1});",
|
||||
kDropInternalIndex, kRemoveInternalLabelProperty);
|
||||
}
|
||||
}
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, CheckStateVertexWithMultipleProperties) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
std::map<std::string, PropertyValue> prop1 = {
|
||||
@ -521,12 +544,12 @@ TEST(DumpTest, CheckStateVertexWithMultipleProperties) {
|
||||
CreateVertex(
|
||||
&dba, {"Label1", "Label2"},
|
||||
{{"prop1", PropertyValue(prop1)}, {"prop2", PropertyValue("$'\t'")}});
|
||||
dba.Commit();
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
|
||||
database::GraphDb db_dump;
|
||||
storage::Storage db_dump;
|
||||
{
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db);
|
||||
query::AnyStream query_stream(&stream, utils::NewDeleteResource());
|
||||
{
|
||||
auto acc = db.Access();
|
||||
@ -546,7 +569,7 @@ TEST(DumpTest, CheckStateVertexWithMultipleProperties) {
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, CheckStateSimpleGraph) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
auto u = CreateVertex(&dba, {"Person"}, {{"name", PropertyValue("Ivan")}});
|
||||
@ -557,28 +580,31 @@ TEST(DumpTest, CheckStateSimpleGraph) {
|
||||
auto z = CreateVertex(
|
||||
&dba, {"Person"},
|
||||
{{"name", PropertyValue("Buha")}, {"id", PropertyValue(1)}});
|
||||
CreateEdge(&dba, u, v, "Knows", {});
|
||||
CreateEdge(&dba, v, w, "Knows", {{"how_long", PropertyValue(5)}});
|
||||
CreateEdge(&dba, w, u, "Knows", {{"how", PropertyValue("distant past")}});
|
||||
CreateEdge(&dba, v, u, "Knows", {});
|
||||
CreateEdge(&dba, v, u, "Likes", {});
|
||||
CreateEdge(&dba, z, u, "Knows", {});
|
||||
CreateEdge(&dba, w, z, "Knows", {{"how", PropertyValue("school")}});
|
||||
CreateEdge(&dba, w, z, "Likes", {{"how", PropertyValue("very much")}});
|
||||
dba.Commit();
|
||||
CreateEdge(&dba, &u, &v, "Knows", {});
|
||||
CreateEdge(&dba, &v, &w, "Knows", {{"how_long", PropertyValue(5)}});
|
||||
CreateEdge(&dba, &w, &u, "Knows", {{"how", PropertyValue("distant past")}});
|
||||
CreateEdge(&dba, &v, &u, "Knows", {});
|
||||
CreateEdge(&dba, &v, &u, "Likes", {});
|
||||
CreateEdge(&dba, &z, &u, "Knows", {});
|
||||
CreateEdge(&dba, &w, &z, "Knows", {{"how", PropertyValue("school")}});
|
||||
CreateEdge(&dba, &w, &z, "Likes", {{"how", PropertyValue("very much")}});
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
{
|
||||
auto dba = db.Access();
|
||||
dba.BuildUniqueConstraint(dba.Label("Person"), {dba.Property("name")});
|
||||
dba.BuildIndex(dba.Label("Person"), dba.Property("id"));
|
||||
dba.BuildIndex(dba.Label("Person"), dba.Property("unexisting_property"));
|
||||
dba.Commit();
|
||||
auto ret = db.CreateExistenceConstraint(db.NameToLabel("Person"),
|
||||
db.NameToProperty("name"));
|
||||
ASSERT_TRUE(ret.HasValue());
|
||||
ASSERT_TRUE(ret.GetValue());
|
||||
}
|
||||
ASSERT_TRUE(
|
||||
db.CreateIndex(db.NameToLabel("Person"), db.NameToProperty("id")));
|
||||
ASSERT_TRUE(db.CreateIndex(db.NameToLabel("Person"),
|
||||
db.NameToProperty("unexisting_property")));
|
||||
|
||||
const auto &db_initial_state = GetState(&db);
|
||||
database::GraphDb db_dump;
|
||||
storage::Storage db_dump;
|
||||
{
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&db);
|
||||
query::AnyStream query_stream(&stream, utils::NewDeleteResource());
|
||||
{
|
||||
auto acc = db.Access();
|
||||
@ -602,11 +628,11 @@ TEST(DumpTest, CheckStateSimpleGraph) {
|
||||
|
||||
// NOLINTNEXTLINE(hicpp-special-member-functions)
|
||||
TEST(DumpTest, ExecuteDumpDatabase) {
|
||||
database::GraphDb db;
|
||||
storage::Storage db;
|
||||
{
|
||||
auto dba = db.Access();
|
||||
CreateVertex(&dba, {}, {}, false);
|
||||
dba.Commit();
|
||||
ASSERT_FALSE(dba.Commit().HasError());
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "communication/result_stream_faker.hpp"
|
||||
#include "database/single_node/graph_db.hpp"
|
||||
#include "query/context.hpp"
|
||||
#include "query/exceptions.hpp"
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "communication/result_stream_faker.hpp"
|
||||
#include "query/context.hpp"
|
||||
#include "query/exceptions.hpp"
|
||||
#include "query/plan/operator.hpp"
|
||||
|
@ -429,7 +429,8 @@ class FakeDbAccessor {
|
||||
storage::Label NameToLabel(const std::string &name) {
|
||||
auto found = labels_.find(name);
|
||||
if (found != labels_.end()) return found->second;
|
||||
return labels_.emplace(name, storage::Label(labels_.size())).first->second;
|
||||
return labels_.emplace(name, storage::Label::FromUint(labels_.size()))
|
||||
.first->second;
|
||||
}
|
||||
|
||||
storage::Label Label(const std::string &name) { return NameToLabel(name); }
|
||||
@ -437,14 +438,16 @@ class FakeDbAccessor {
|
||||
storage::EdgeType NameToEdgeType(const std::string &name) {
|
||||
auto found = edge_types_.find(name);
|
||||
if (found != edge_types_.end()) return found->second;
|
||||
return edge_types_.emplace(name, storage::EdgeType(edge_types_.size()))
|
||||
return edge_types_
|
||||
.emplace(name, storage::EdgeType::FromUint(edge_types_.size()))
|
||||
.first->second;
|
||||
}
|
||||
|
||||
storage::Property NameToProperty(const std::string &name) {
|
||||
auto found = properties_.find(name);
|
||||
if (found != properties_.end()) return found->second;
|
||||
return properties_.emplace(name, storage::Property(properties_.size()))
|
||||
return properties_
|
||||
.emplace(name, storage::Property::FromUint(properties_.size()))
|
||||
.first->second;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "communication/result_stream_faker.hpp"
|
||||
#include "query/context.hpp"
|
||||
#include "query/exceptions.hpp"
|
||||
#include "query/interpret/frame.hpp"
|
||||
|
@ -8,15 +8,14 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "communication/result_stream_faker.hpp"
|
||||
#include "database/single_node/graph_db.hpp"
|
||||
#include "database/single_node/graph_db_accessor.hpp"
|
||||
#include "query/interpreter.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
|
||||
DECLARE_bool(query_cost_planner);
|
||||
|
||||
class QueryExecution : public testing::Test {
|
||||
protected:
|
||||
std::optional<database::GraphDb> db_;
|
||||
std::optional<storage::Storage> db_;
|
||||
std::optional<query::InterpreterContext> interpreter_context_;
|
||||
std::optional<query::Interpreter> interpreter_;
|
||||
|
||||
@ -38,7 +37,7 @@ class QueryExecution : public testing::Test {
|
||||
* Return the query results.
|
||||
*/
|
||||
auto Execute(const std::string &query) {
|
||||
ResultStreamFaker stream;
|
||||
ResultStreamFaker stream(&*db_);
|
||||
|
||||
auto [header, _] = interpreter_->Prepare(query, {});
|
||||
stream.Header(header);
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <cppitertools/range.hpp>
|
||||
#include <cppitertools/repeat.hpp>
|
||||
|
||||
#include "communication/result_stream_faker.hpp"
|
||||
#include "database/single_node/graph_db.hpp"
|
||||
#include "query/context.hpp"
|
||||
#include "query/exceptions.hpp"
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "database/single_node/graph_db_accessor.hpp"
|
||||
#include "query/frontend/ast/ast.hpp"
|
||||
#include "query/frontend/ast/pretty_print.hpp"
|
||||
#include "query_common.hpp"
|
||||
@ -17,10 +16,9 @@ using testing::UnorderedElementsAre;
|
||||
namespace {
|
||||
|
||||
struct ExpressionPrettyPrinterTest : public ::testing::Test {
|
||||
ExpressionPrettyPrinterTest() : dba{db.Access()} {}
|
||||
|
||||
database::GraphDb db;
|
||||
database::GraphDbAccessor dba;
|
||||
storage::Storage db;
|
||||
storage::Storage::Accessor storage_dba{db.Access()};
|
||||
query::DbAccessor dba{&storage_dba};
|
||||
AstStorage storage;
|
||||
};
|
||||
|
||||
@ -62,7 +60,7 @@ TEST_F(ExpressionPrettyPrinterTest, Identifiers) {
|
||||
|
||||
TEST_F(ExpressionPrettyPrinterTest, Reducing) {
|
||||
// all(x in list where x.prop = 42)
|
||||
auto prop = dba.Property("prop");
|
||||
auto prop = dba.NameToProperty("prop");
|
||||
EXPECT_EQ(ToString(ALL("x", LITERAL(std::vector<PropertyValue>{}),
|
||||
WHERE(EQ(PROPERTY_LOOKUP("x", prop), LITERAL(42))))),
|
||||
"(All (Identifier \"x\") [] (== (PropertyLookup "
|
||||
|
@ -3,8 +3,6 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "database/single_node/graph_db.hpp"
|
||||
#include "database/single_node/graph_db_accessor.hpp"
|
||||
#include "query/frontend/ast/ast.hpp"
|
||||
#include "query/frontend/semantic/symbol_generator.hpp"
|
||||
#include "query/frontend/semantic/symbol_table.hpp"
|
||||
@ -15,8 +13,9 @@ using namespace query;
|
||||
|
||||
class TestSymbolGenerator : public ::testing::Test {
|
||||
protected:
|
||||
database::GraphDb db;
|
||||
database::GraphDbAccessor dba{db.Access()};
|
||||
storage::Storage db;
|
||||
storage::Storage::Accessor storage_dba{db.Access()};
|
||||
query::DbAccessor dba{&storage_dba};
|
||||
AstStorage storage;
|
||||
};
|
||||
|
||||
@ -240,7 +239,7 @@ TEST_F(TestSymbolGenerator, MatchWithReturnUnbound) {
|
||||
|
||||
TEST_F(TestSymbolGenerator, MatchWithWhere) {
|
||||
// Test MATCH (old) WITH old AS n WHERE n.prop < 42
|
||||
auto prop = dba.Property("prop");
|
||||
auto prop = dba.NameToProperty("prop");
|
||||
auto node = NODE("old");
|
||||
auto old_ident = IDENT("old");
|
||||
auto with_as_n = AS("n");
|
||||
@ -262,7 +261,7 @@ TEST_F(TestSymbolGenerator, MatchWithWhere) {
|
||||
|
||||
TEST_F(TestSymbolGenerator, MatchWithWhereUnbound) {
|
||||
// Test MATCH (old) WITH COUNT(old) AS c WHERE old.prop < 42
|
||||
auto prop = dba.Property("prop");
|
||||
auto prop = dba.NameToProperty("prop");
|
||||
auto query = QUERY(SINGLE_QUERY(
|
||||
MATCH(PATTERN(NODE("old"))), WITH(COUNT(IDENT("old")), AS("c")),
|
||||
WHERE(LESS(PROPERTY_LOOKUP("old", prop), LITERAL(42)))));
|
||||
@ -325,7 +324,7 @@ TEST_F(TestSymbolGenerator, CreateExpandProperty) {
|
||||
|
||||
TEST_F(TestSymbolGenerator, MatchReturnSum) {
|
||||
// Test MATCH (n) RETURN SUM(n.prop) + 42 AS result
|
||||
auto prop = dba.Property("prop");
|
||||
auto prop = dba.NameToProperty("prop");
|
||||
auto node = NODE("n");
|
||||
auto sum = SUM(PROPERTY_LOOKUP("n", prop));
|
||||
auto as_result = AS("result");
|
||||
@ -344,7 +343,7 @@ TEST_F(TestSymbolGenerator, MatchReturnSum) {
|
||||
|
||||
TEST_F(TestSymbolGenerator, NestedAggregation) {
|
||||
// Test MATCH (n) RETURN SUM(42 + SUM(n.prop)) AS s
|
||||
auto prop = dba.Property("prop");
|
||||
auto prop = dba.NameToProperty("prop");
|
||||
auto query = QUERY(SINGLE_QUERY(
|
||||
MATCH(PATTERN(NODE("n"))),
|
||||
RETURN(SUM(ADD(LITERAL(42), SUM(PROPERTY_LOOKUP("n", prop)))), AS("s"))));
|
||||
@ -353,7 +352,7 @@ TEST_F(TestSymbolGenerator, NestedAggregation) {
|
||||
|
||||
TEST_F(TestSymbolGenerator, WrongAggregationContext) {
|
||||
// Test MATCH (n) WITH n.prop AS prop WHERE SUM(prop) < 42
|
||||
auto prop = dba.Property("prop");
|
||||
auto prop = dba.NameToProperty("prop");
|
||||
auto query = QUERY(SINGLE_QUERY(
|
||||
MATCH(PATTERN(NODE("n"))), WITH(PROPERTY_LOOKUP("n", prop), AS("prop")),
|
||||
WHERE(LESS(SUM(IDENT("prop")), LITERAL(42)))));
|
||||
@ -534,7 +533,7 @@ TEST_F(TestSymbolGenerator, MergeOnMatchOnCreate) {
|
||||
// Test MATCH (n) MERGE (n) -[r :rel]- (m) ON MATCH SET n.prop = 42
|
||||
// ON CREATE SET m.prop = 42 RETURN r AS r
|
||||
auto rel = "rel";
|
||||
auto prop = dba.Property("prop");
|
||||
auto prop = dba.NameToProperty("prop");
|
||||
auto match_n = NODE("n");
|
||||
auto merge_n = NODE("n");
|
||||
auto edge_r = EDGE("r", EdgeAtom::Direction::BOTH, {rel});
|
||||
@ -630,7 +629,7 @@ TEST_F(TestSymbolGenerator, MatchCrossReferenceVariable) {
|
||||
|
||||
TEST_F(TestSymbolGenerator, MatchWithAsteriskReturnAsterisk) {
|
||||
// MATCH (n) -[e]- (m) WITH * RETURN *, n.prop
|
||||
auto prop = dba.Property("prop");
|
||||
auto prop = dba.NameToProperty("prop");
|
||||
auto n_prop = PROPERTY_LOOKUP("n", prop);
|
||||
auto ret = RETURN(n_prop, AS("n.prop"));
|
||||
ret->body_.all_identifiers = true;
|
||||
@ -697,7 +696,7 @@ TEST_F(TestSymbolGenerator, MatchEdgeWithIdentifierInProperty) {
|
||||
|
||||
TEST_F(TestSymbolGenerator, MatchVariablePathUsingIdentifier) {
|
||||
// Test MATCH (n) -[r *..l.prop]- (m), (l) RETURN r
|
||||
auto prop = dba.Property("prop");
|
||||
auto prop = dba.NameToProperty("prop");
|
||||
auto edge = EDGE_VARIABLE("r");
|
||||
auto l_prop = PROPERTY_LOOKUP("l", prop);
|
||||
edge->upper_bound_ = l_prop;
|
||||
@ -718,7 +717,7 @@ TEST_F(TestSymbolGenerator, MatchVariablePathUsingIdentifier) {
|
||||
|
||||
TEST_F(TestSymbolGenerator, MatchVariablePathUsingUnboundIdentifier) {
|
||||
// Test MATCH (n) -[r *..l.prop]- (m) MATCH (l) RETURN r
|
||||
auto prop = dba.Property("prop");
|
||||
auto prop = dba.NameToProperty("prop");
|
||||
auto edge = EDGE_VARIABLE("r");
|
||||
auto l_prop = PROPERTY_LOOKUP("l", prop);
|
||||
edge->upper_bound_ = l_prop;
|
||||
@ -762,7 +761,7 @@ TEST_F(TestSymbolGenerator, VariablePathSameIdentifier) {
|
||||
// Test MATCH (n) -[r *r.prop..]-> (m) RETURN r raises UnboundVariableError.
|
||||
// `r` cannot be used inside the range expression, since it is bound by the
|
||||
// variable expansion itself.
|
||||
auto prop = dba.Property("prop");
|
||||
auto prop = dba.NameToProperty("prop");
|
||||
auto edge =
|
||||
EDGE_VARIABLE("r", EdgeAtom::Type::DEPTH_FIRST, EdgeAtom::Direction::OUT);
|
||||
edge->lower_bound_ = PROPERTY_LOOKUP("r", prop);
|
||||
@ -890,7 +889,7 @@ TEST_F(TestSymbolGenerator, WithReturnExtract) {
|
||||
|
||||
TEST_F(TestSymbolGenerator, MatchBfsReturn) {
|
||||
// Test MATCH (n) -[r *bfs..n.prop] (r, n | r.prop)]-> (m) RETURN r AS r
|
||||
auto prop = dba.Property("prop");
|
||||
auto prop = dba.NameToProperty("prop");
|
||||
auto *node_n = NODE("n");
|
||||
auto *r_prop = PROPERTY_LOOKUP("r", prop);
|
||||
auto *n_prop = PROPERTY_LOOKUP("n", prop);
|
||||
@ -995,8 +994,8 @@ TEST_F(TestSymbolGenerator, MatchVariableLambdaSymbols) {
|
||||
TEST_F(TestSymbolGenerator, MatchWShortestReturn) {
|
||||
// Test MATCH (n) -[r *wShortest (r, n | r.weight) (r, n | r.filter)]-> (m)
|
||||
// RETURN r AS r
|
||||
auto weight = dba.Property("weight");
|
||||
auto filter = dba.Property("filter");
|
||||
auto weight = dba.NameToProperty("weight");
|
||||
auto filter = dba.NameToProperty("filter");
|
||||
auto *node_n = NODE("n");
|
||||
auto *r_weight = PROPERTY_LOOKUP("r", weight);
|
||||
auto *r_filter = PROPERTY_LOOKUP("r", filter);
|
||||
@ -1188,4 +1187,3 @@ TEST_F(TestSymbolGenerator, CallProcedureUnboundArgument) {
|
||||
auto query = QUERY(SINGLE_QUERY(call));
|
||||
EXPECT_THROW(query::MakeSymbolTable(query), SemanticException);
|
||||
}
|
||||
|
||||
|
@ -9,8 +9,8 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "database/single_node/graph_db_accessor.hpp"
|
||||
#include "query/typed_value.hpp"
|
||||
#include "storage/v2/storage.hpp"
|
||||
|
||||
using query::TypedValue;
|
||||
using query::TypedValueException;
|
||||
@ -18,8 +18,9 @@ using query::TypedValueException;
|
||||
class AllTypesFixture : public testing::Test {
|
||||
protected:
|
||||
std::vector<TypedValue> values_;
|
||||
database::GraphDb db_;
|
||||
database::GraphDbAccessor dba_{db_.Access()};
|
||||
storage::Storage db;
|
||||
storage::Storage::Accessor storage_dba{db.Access()};
|
||||
query::DbAccessor dba{&storage_dba};
|
||||
|
||||
void SetUp() override {
|
||||
values_.emplace_back(TypedValue());
|
||||
@ -36,12 +37,11 @@ class AllTypesFixture : public testing::Test {
|
||||
{"c", TypedValue(42)},
|
||||
{"d", TypedValue(0.5)},
|
||||
{"e", TypedValue()}});
|
||||
auto vertex = dba_.InsertVertex();
|
||||
values_.emplace_back(query::VertexAccessor(vertex));
|
||||
values_.emplace_back(query::EdgeAccessor(
|
||||
dba_.InsertEdge(vertex, vertex, dba_.EdgeType("et"))));
|
||||
auto vertex = dba.InsertVertex();
|
||||
values_.emplace_back(vertex);
|
||||
values_.emplace_back(
|
||||
query::Path(query::VertexAccessor(dba_.InsertVertex())));
|
||||
*dba.InsertEdge(&vertex, &vertex, dba.NameToEdgeType("et")));
|
||||
values_.emplace_back(query::Path(dba.InsertVertex()));
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user