Hardcoded query infrastructure - first concrete version - USEFUL FOR: POCs & pilots
Summary: Hardcoded query infrastructure - first concrete version - USEFUL FOR: POCs & pilots Test Plan: manual + jenkins Reviewers: sale, florijan Reviewed By: florijan Subscribers: pullbot, buda Differential Revision: https://phabricator.memgraph.io/D45
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
#include "query/preprocesor.hpp"
|
||||
#include "query/preprocessor.hpp"
|
||||
#include "utils/time/timer.hpp"
|
||||
|
||||
#include "benchmark/benchmark_api.h"
|
||||
@@ -27,7 +27,7 @@ int main(int argc, char **argv)
|
||||
|
||||
QueryPreprocessor processor;
|
||||
using std::placeholders::_1;
|
||||
std::function<QueryStripped(const std::string &query)> preprocess =
|
||||
std::function<StrippedQuery<QueryPreprocessor::HashT>(const std::string &query)> preprocess =
|
||||
std::bind(&QueryPreprocessor::preprocess, &processor, _1);
|
||||
|
||||
auto tests = dataset["benchmark_queries"].as<std::vector<std::string>>();
|
||||
|
||||
4
tests/data/queries/core/mg_basic_000.txt
Normal file
4
tests/data/queries/core/mg_basic_000.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
CREATE (g:garment {garment_id: 1234, garment_category_id: 1}) RETURN g
|
||||
CREATE (g:garment {garment_id: 1235, garment_category_id: 1}) RETURN g
|
||||
CREATE (p:profile {profile_id: 111, partner_id: 55}) RETURN p
|
||||
CREATE (p:profile {profile_id: 112, partner_id: 55}) RETURN p
|
||||
@@ -26,6 +26,8 @@ foreach(test_cpp ${test_type_cpps})
|
||||
set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${exec_name})
|
||||
|
||||
# link libraries
|
||||
target_link_libraries(${target_name} dl)
|
||||
target_link_libraries(${target_name} cypher_lib)
|
||||
# filesystem
|
||||
target_link_libraries(${target_name} stdc++fs)
|
||||
# threads (cross-platform)
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#include "communication/bolt/v1/serialization/bolt_serializer.hpp"
|
||||
#include "communication/bolt/v1/serialization/record_stream.hpp"
|
||||
#include "database/db.hpp"
|
||||
#include "database/db.hpp"
|
||||
#include "database/db_accessor.hpp"
|
||||
#include "database/db_accessor.hpp"
|
||||
#include "io/network/socket.hpp"
|
||||
#include "mvcc/id.hpp"
|
||||
@@ -25,7 +23,6 @@
|
||||
#include "storage/model/properties/property.hpp"
|
||||
#include "utils/border.hpp"
|
||||
#include "utils/iterator/iterator.hpp"
|
||||
#include "utils/iterator/iterator.hpp"
|
||||
#include "utils/option_ptr.hpp"
|
||||
#include "utils/reference_wrapper.hpp"
|
||||
#include "utils/variadic/variadic.hpp"
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
// TODO: refactor (backlog task)
|
||||
|
||||
#include "_hardcoded_query/basic.hpp"
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
#include "query/preprocesor.hpp"
|
||||
#include "query/strip/stripper.hpp"
|
||||
#include "query/preprocessor.hpp"
|
||||
#include "query/stripper.hpp"
|
||||
#include "utils/assert.hpp"
|
||||
#include "utils/sysinfo/memory.hpp"
|
||||
|
||||
QueryPreprocessor preprocessor;
|
||||
|
||||
template <class Q>
|
||||
void run(size_t n, std::string &query, Q &qf)
|
||||
{
|
||||
QueryPreprocessor preprocessor;
|
||||
auto stripped = preprocessor.preprocess(query);
|
||||
|
||||
logging::info("Running query [{}] x {}.", stripped.hash, n);
|
||||
@@ -31,7 +32,7 @@ void clean_vertex(Db &db)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
logging::init_async();
|
||||
logging::init_sync();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
|
||||
Db db("cleaning");
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "query/util.hpp"
|
||||
#include "storage/edge_x_vertex.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
@@ -16,6 +16,8 @@ using std::endl;
|
||||
|
||||
// Dressipi astar query of 4 clicks.
|
||||
|
||||
// Query: MATCH (a:garment)-[:default_outfit]-(b:garment)-[:default_outfit]-(c:garment)-[:default_outfit]-(d:garment)-[:default_outfit]-(a:garment)-[:default_outfit]-(c:garment), (b:garment)-[:default_outfit]-(d:garment) RETURN a.garment_id,b.garment_id,c.garment_id,d.garment_id
|
||||
|
||||
// TODO: figure out from the pattern in a query
|
||||
constexpr size_t max_depth = 3;
|
||||
|
||||
@@ -139,10 +141,10 @@ void reverse_stream_ids(Node *node, Stream& stream, VertexPropertyKey key)
|
||||
stream.write(node->vacc.at(key).template as<Int64>());
|
||||
}
|
||||
|
||||
class PlanCPU : public IPlanCPU<Stream>
|
||||
class PlanCPU : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -180,6 +182,6 @@ public:
|
||||
~PlanCPU() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream> *produce() { return new PlanCPU(); }
|
||||
extern "C" PlanInterface<Stream> *produce() { return new PlanCPU(); }
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream> *p) { delete p; }
|
||||
extern "C" void destruct(PlanInterface<Stream> *p) { delete p; }
|
||||
58
tests/integration/hardcoded_query/create_account_return.cpp
Normal file
58
tests/integration/hardcoded_query/create_account_return.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "storage/edge_x_vertex.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: CREATE (n:ACCOUNT {id: 2322, name: "TEST", country: "Croatia", "created_at": 2352352}) RETURN n
|
||||
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
auto prop_id = t.vertex_property_key("id", args[0].key.flags());
|
||||
auto prop_name = t.vertex_property_key("name", args[1].key.flags());
|
||||
auto prop_country =
|
||||
t.vertex_property_key("country", args[2].key.flags());
|
||||
auto prop_created =
|
||||
t.vertex_property_key("created_at", args[3].key.flags());
|
||||
|
||||
auto &label = t.label_find_or_create("ACCOUNT");
|
||||
|
||||
auto vertex_accessor = t.vertex_insert();
|
||||
|
||||
vertex_accessor.set(prop_id, std::move(args[0]));
|
||||
vertex_accessor.set(prop_name, std::move(args[1]));
|
||||
vertex_accessor.set(prop_country, std::move(args[2]));
|
||||
vertex_accessor.set(prop_created, std::move(args[3]));
|
||||
vertex_accessor.add_label(label);
|
||||
|
||||
stream.write_field("p");
|
||||
stream.write_vertex_record(vertex_accessor);
|
||||
stream.write_meta("w");
|
||||
|
||||
return t.commit();
|
||||
}
|
||||
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
52
tests/integration/hardcoded_query/create_edge.cpp
Normal file
52
tests/integration/hardcoded_query/create_edge.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "storage/edge_x_vertex.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: MATCH (a {id:0}), (p {id: 1}) CREATE (a)-[r:IS]->(p) RETURN r
|
||||
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
auto &edge_type = t.type_find_or_create("IS");
|
||||
|
||||
auto v1 = t.vertex_find(args[0].as<Int64>().value());
|
||||
if (!option_fill(v1)) return t.commit(), false;
|
||||
|
||||
auto v2 = t.vertex_find(args[1].as<Int64>().value());
|
||||
if (!option_fill(v2)) return t.commit(), false;
|
||||
|
||||
auto edge_accessor = t.edge_insert(v1.get(), v2.get());
|
||||
|
||||
edge_accessor.edge_type(edge_type);
|
||||
|
||||
stream.write_field("r");
|
||||
stream.write_edge_record(edge_accessor);
|
||||
stream.write_meta("w");
|
||||
|
||||
return t.commit();
|
||||
}
|
||||
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,21 +2,20 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: CREATE (p:profile {profile_id: 111, partner_id: 55}) RETURN p
|
||||
// Hash: 17158428452166262783
|
||||
// Query: CREATE (p:profile {profile_id: 112, partner_id: 55}) RETURN p
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -40,15 +39,15 @@ public:
|
||||
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "storage/edge_x_vertex.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: CREATE (n:LABEL {name: "TEST"}) RETURN n
|
||||
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
auto property_key = t.vertex_property_key("name", args[0].key.flags());
|
||||
auto &label = t.label_find_or_create("LABEL");
|
||||
|
||||
auto vertex_accessor = t.vertex_insert();
|
||||
vertex_accessor.set(property_key, std::move(args[0]));
|
||||
vertex_accessor.add_label(label);
|
||||
|
||||
stream.write_field("n");
|
||||
stream.write_vertex_record(vertex_accessor);
|
||||
stream.write_meta("w");
|
||||
|
||||
return t.commit();
|
||||
}
|
||||
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "storage/edge_x_vertex.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: CREATE (n:OTHER {name: "cleaner_test"}) RETURN n
|
||||
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
auto property_key = t.vertex_property_key("name", args[0].key.flags());
|
||||
auto &label = t.label_find_or_create("OTHER");
|
||||
|
||||
auto vertex_accessor = t.vertex_insert();
|
||||
vertex_accessor.set(property_key, std::move(args[0]));
|
||||
vertex_accessor.add_label(label);
|
||||
|
||||
stream.write_field("n");
|
||||
stream.write_vertex_record(vertex_accessor);
|
||||
stream.write_meta("w");
|
||||
|
||||
return t.commit();
|
||||
}
|
||||
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
46
tests/integration/hardcoded_query/create_prop_return.cpp
Normal file
46
tests/integration/hardcoded_query/create_prop_return.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "storage/edge_x_vertex.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: CREATE (n {prop: 0}) RETURN n
|
||||
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
auto property_key = t.vertex_property_key("prop", args[0].key.flags());
|
||||
|
||||
auto vertex_accessor = t.vertex_insert();
|
||||
vertex_accessor.set(property_key, std::move(args[0]));
|
||||
|
||||
stream.write_field("n");
|
||||
stream.write_vertex_record(vertex_accessor);
|
||||
stream.write_meta("w");
|
||||
|
||||
return t.commit();
|
||||
}
|
||||
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,21 +2,20 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: CREATE (g:garment {garment_id: 1234, garment_category_id: 1}) RETURN g
|
||||
// Hash: 18071907865596388702
|
||||
// Query: CREATE (g:garment {garment_id: 1236, garment_category_id: 1}) RETURN g
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -39,15 +38,15 @@ public:
|
||||
return t.commit();
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
@@ -10,13 +10,12 @@ using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: MATCH (n) DETACH DELETE n
|
||||
// Hash: 4798158026600988079
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -30,15 +29,15 @@ public:
|
||||
return t.commit();
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
@@ -10,13 +10,12 @@ using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: MATCH (p:garment {garment_id: 1}) DELETE g
|
||||
// Hash: 11538263096707897794
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -37,15 +36,15 @@ public:
|
||||
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
@@ -10,13 +10,12 @@ using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: MATCH (p:profile {profile_id: 1}) DELETE p
|
||||
// Hash: 6763665709953344106
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -37,15 +36,15 @@ public:
|
||||
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,21 +2,21 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "storage/edge_x_vertex.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: MATCH (p:profile {profile_id: 111, partner_id:55})-[s:score]-(g.garment {garment_id: 1234}) DELETE s
|
||||
// Hash: 9459600951073026137
|
||||
// Query: MATCH (p:profile {profile_id: 111, partner_id:55})-[s:score]-(g:garment {garment_id: 1234}) DELETE s
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -77,15 +77,15 @@ public:
|
||||
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,21 +2,21 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "storage/edge_x_vertex.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: MATCH (p:profile {profile_id: 111, partner_id:55})-[s:score]-(g:garment {garment_id: 1234}) SET s.score = 1550 RETURN s.score
|
||||
// Hash: 674581607834128909
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -75,15 +75,15 @@ public:
|
||||
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
@@ -10,13 +10,12 @@ using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: MATCH (g:garment {garment_id: 1234}) SET g:FF RETURN labels(g)
|
||||
// Hash: 11123780635391515946
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -46,20 +45,20 @@ public:
|
||||
stream.chunk();
|
||||
});
|
||||
|
||||
stream.write_meta(\"rw");
|
||||
stream.write_meta("rw");
|
||||
|
||||
return t.commit();
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
@@ -10,13 +10,12 @@ using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: MATCH (g:garment {garment_id: 3456}) SET g.reveals = 50 RETURN g
|
||||
// Hash: 2839969099736071844
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -44,15 +43,15 @@ public:
|
||||
return t.commit();
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
@@ -10,13 +10,12 @@ using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: MATCH (p:profile {partner_id: 1}) RETURN p
|
||||
// Hash: 17506488413143988006
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -39,15 +38,15 @@ public:
|
||||
return t.commit();
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
@@ -10,13 +10,12 @@ using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: MATCH (g:garment {garment_id: 1}) RETURN g
|
||||
// Hash: 7756609649964321221
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -39,15 +38,15 @@ public:
|
||||
return t.commit();
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
@@ -10,13 +10,12 @@ using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: MERGE (g1:garment {garment_id:1234})-[r:default_outfit]-(g2:garment {garment_id: 2345}) RETURN r
|
||||
// Hash: 3782642357973971504
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -60,15 +59,15 @@ public:
|
||||
return t.commit();
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "storage/edge_x_vertex.hpp"
|
||||
#include "using.hpp"
|
||||
@@ -11,13 +11,12 @@ using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// Query: MERGE (p:profile {profile_id: 111, partner_id: 55})-[s:score]-(g.garment {garment_id: 1234}) SET s.score=1500 RETURN s
|
||||
// Hash: 7871009397157280694
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
DbAccessor t(db);
|
||||
|
||||
@@ -92,15 +91,15 @@ public:
|
||||
return t.commit();
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
@@ -2,33 +2,34 @@
|
||||
#include <string>
|
||||
|
||||
#include "query/util.hpp"
|
||||
#include "query/i_plan_cpu.hpp"
|
||||
#include "query/plan_interface.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#include "storage/edge_x_vertex.hpp"
|
||||
#include "using.hpp"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
// query:
|
||||
// Query:
|
||||
|
||||
class CodeCPU : public IPlanCPU<Stream>
|
||||
class CPUPlan : public PlanInterface<Stream>
|
||||
{
|
||||
public:
|
||||
|
||||
bool run(Db &db, plan_args_t &args, Stream &stream) override
|
||||
bool run(Db &db, const PlanArgsT &args, Stream &stream) override
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
~CodeCPU() {}
|
||||
~CPUPlan() {}
|
||||
};
|
||||
|
||||
extern "C" IPlanCPU<Stream>* produce()
|
||||
extern "C" PlanInterface<Stream>* produce()
|
||||
{
|
||||
return new CodeCPU();
|
||||
return new CPUPlan();
|
||||
}
|
||||
|
||||
extern "C" void destruct(IPlanCPU<Stream>* p)
|
||||
extern "C" void destruct(PlanInterface<Stream>* p)
|
||||
{
|
||||
delete p;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "communication/communication.hpp"
|
||||
// #include "communication/communication.hpp"
|
||||
// using Stream = communication::OutputStream;
|
||||
|
||||
using Stream = communication::OutputStream;
|
||||
// TODO: modular
|
||||
#include "../stream/print_record_stream.hpp"
|
||||
using Stream = PrintRecordStream;
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
// TODO: refactor (backlog task)
|
||||
|
||||
#include <random>
|
||||
|
||||
#include "_hardcoded_query/basic.hpp"
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
#include "query/preprocesor.hpp"
|
||||
#include "query/strip/stripper.hpp"
|
||||
#include "query/preprocessor.hpp"
|
||||
#include "query/stripper.hpp"
|
||||
#include "storage/indexes/indexes.hpp"
|
||||
#include "utils/assert.hpp"
|
||||
#include "utils/signals/handler.hpp"
|
||||
#include "utils/stacktrace/log.hpp"
|
||||
#include "utils/sysinfo/memory.hpp"
|
||||
|
||||
QueryPreprocessor preprocessor;
|
||||
|
||||
// Returns uniform random size_t generator from range [0,n>
|
||||
auto rand_gen(size_t n)
|
||||
{
|
||||
@@ -24,6 +24,7 @@ auto rand_gen(size_t n)
|
||||
void run(size_t n, std::string &query, Db &db)
|
||||
{
|
||||
auto qf = hardcode::load_basic_functions(db);
|
||||
QueryPreprocessor preprocessor;
|
||||
auto stripped = preprocessor.preprocess(query);
|
||||
|
||||
logging::info("Running query [{}] x {}.", stripped.hash, n);
|
||||
@@ -42,6 +43,7 @@ void add_edge(size_t n, Db &db)
|
||||
std::string query = "MATCH (n1), (n2) WHERE ID(n1)=0 AND "
|
||||
"ID(n2)=1 CREATE (n1)<-[r:IS {age: "
|
||||
"25,weight: 70}]-(n2) RETURN r";
|
||||
QueryPreprocessor preprocessor;
|
||||
auto stripped = preprocessor.preprocess(query);
|
||||
|
||||
logging::info("Running query [{}] (add edge) x {}", stripped.hash, n);
|
||||
@@ -196,7 +198,7 @@ bool equal(Db &a, Db &b)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
logging::init_async();
|
||||
logging::init_sync();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
|
||||
SignalHandler::register_handler(Signal::SegmentationFault, []() {
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#include "communication/bolt/v1/serialization/bolt_serializer.hpp"
|
||||
#include "database/db.hpp"
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
#include "_hardcoded_query/basic.hpp"
|
||||
#include "_hardcoded_query/dressipi.hpp"
|
||||
#include "query/strip/stripper.hpp"
|
||||
#include "utils/string/file.hpp"
|
||||
#include "utils/variadic/variadic.hpp"
|
||||
#include "utils/command_line/arguments.hpp"
|
||||
#include "stream/print_record_stream.hpp"
|
||||
|
||||
Logger logger;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
auto arguments = all_arguments(argc, argv);
|
||||
|
||||
PrintRecordStream stream(std::cout);
|
||||
|
||||
// POSSIBILITIES: basic, dressipi
|
||||
auto suite_name = get_argument(arguments, "-s", "basic");
|
||||
// POSSIBILITIES: query_execution, hash_generation
|
||||
auto work_mode = get_argument(arguments, "-w", "query_execution");
|
||||
// POSSIBILITIES: mg_basic.txt, dressipi_basic.txt, dressipi_graph.txt
|
||||
auto query_set_filename = get_argument(arguments, "-q", "mg_basic.txt");
|
||||
|
||||
// init logging
|
||||
logging::init_sync();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
auto log = logging::log->logger("test");
|
||||
|
||||
// init db, functions and stripper
|
||||
Db db;
|
||||
hardcode::query_functions_t query_functions;
|
||||
if (suite_name == "dressipi")
|
||||
{
|
||||
query_functions = std::move(hardcode::load_dressipi_functions(db));
|
||||
}
|
||||
else
|
||||
{
|
||||
query_functions = std::move(hardcode::load_basic_functions(db));
|
||||
}
|
||||
auto stripper = make_query_stripper(TK_LONG, TK_FLOAT, TK_STR, TK_BOOL);
|
||||
|
||||
// load quries
|
||||
std::string file_path = "data/queries/core/" + query_set_filename;
|
||||
auto queries = utils::read_lines(file_path.c_str());
|
||||
|
||||
// execute all queries
|
||||
for (auto &query : queries)
|
||||
{
|
||||
if (query.empty())
|
||||
continue;
|
||||
|
||||
utils::println("");
|
||||
utils::println("Query: ", query);
|
||||
|
||||
auto stripped = stripper.strip(query);
|
||||
utils::println("Hash: ", stripped.hash);
|
||||
|
||||
utils::println("------------------------");
|
||||
|
||||
// TODO: more robust solution (enum like)
|
||||
if (work_mode == "hash_generation") continue;
|
||||
|
||||
auto result =
|
||||
query_functions[stripped.hash](std::move(stripped.arguments));
|
||||
permanent_assert(result == true,
|
||||
"Result retured from query function is not true");
|
||||
utils::println("------------------------");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
35
tests/integration/query_engine.cpp
Normal file
35
tests/integration/query_engine.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "query_engine_common.hpp"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
using namespace tests::integration;
|
||||
|
||||
Logger logger;
|
||||
|
||||
/**
|
||||
* IMPORTANT: tests only compilation and executability of implemented
|
||||
* hard code queries (not correctnes of implementation)
|
||||
*
|
||||
* NOTE: The correctnes can be tested by custom Stream object.
|
||||
* NOTE: This test will be usefull to test generated query plans.
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
/**
|
||||
* init arguments
|
||||
*/
|
||||
REGISTER_ARGS(argc, argv);
|
||||
|
||||
/**
|
||||
* init engine
|
||||
*/
|
||||
auto log = init_logging("IntegrationQueryEngine");
|
||||
Db db;
|
||||
StreamT stream(std::cout);
|
||||
QueryEngineT query_engine;
|
||||
// IMPORTANT: PrintRecordStream can be replaces with a smarter
|
||||
// object that can test the results
|
||||
|
||||
WarmUpEngine(log, query_engine, db, stream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
179
tests/integration/query_engine_common.hpp
Normal file
179
tests/integration/query_engine_common.hpp
Normal file
@@ -0,0 +1,179 @@
|
||||
#pragma once
|
||||
|
||||
#include <experimental/filesystem>
|
||||
#include <set>
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#include "database/db.hpp"
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.cpp"
|
||||
#include "query/engine.hpp"
|
||||
#include "query/preprocessor.hpp"
|
||||
#include "stream/print_record_stream.hpp"
|
||||
#include "utils/command_line/arguments.hpp"
|
||||
#include "utils/file.hpp"
|
||||
#include "utils/string/file.hpp"
|
||||
#include "utils/string/trim.hpp"
|
||||
|
||||
namespace tests
|
||||
{
|
||||
namespace integration
|
||||
{
|
||||
|
||||
using namespace utils;
|
||||
using QueryHashesT = std::set<QueryPreprocessor::HashT>;
|
||||
using QueryEngineT = QueryEngine<PrintRecordStream>;
|
||||
using StreamT = PrintRecordStream;
|
||||
|
||||
/**
|
||||
* Init logging for tested query_engine (test specific logger). It has to be
|
||||
* sync (easier debugging).
|
||||
*
|
||||
* @param logger_name the name of a logger
|
||||
*
|
||||
* @return logger instance
|
||||
*/
|
||||
auto init_logging(const std::string &logger_name)
|
||||
{
|
||||
logging::init_sync();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
return logging::log->logger(logger_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get query hashes from the file defied with a path.
|
||||
*
|
||||
* @param log external logger because this function should be called
|
||||
* from test binaries
|
||||
* @param path path to a file with queries
|
||||
*
|
||||
* @return a set with all query hashes from the file
|
||||
*/
|
||||
auto LoadQueryHashes(Logger &log, const fs::path &path)
|
||||
{
|
||||
log.info("*** Get query hashes from the file defied with path ***");
|
||||
// the intention of following block is to get all hashes
|
||||
// for which query implementations have to be compiled
|
||||
// calculate all hashes from queries file
|
||||
QueryPreprocessor preprocessor;
|
||||
// hashes calculated from all queries in queries file
|
||||
QueryHashesT query_hashes;
|
||||
// fill the above set
|
||||
auto queries = utils::read_lines(path);
|
||||
for (auto &query : queries)
|
||||
{
|
||||
if (query.empty()) continue;
|
||||
query_hashes.insert(preprocessor.preprocess(query).hash);
|
||||
}
|
||||
permanent_assert(query_hashes.size() > 0,
|
||||
"At least one hash has to be present");
|
||||
log.info("{} different query hashes exist", query_hashes.size());
|
||||
return query_hashes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads query plans into the engine passed by reference.
|
||||
*
|
||||
* @param log external logger reference
|
||||
* @param engine query engine
|
||||
* @param query_hashes hashes for which plans have to be loaded
|
||||
* @param path to a folder with query plan implementations
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
auto LoadQueryPlans(Logger &log, QueryEngineT &engine,
|
||||
const QueryHashesT &query_hashes, const fs::path &path)
|
||||
{
|
||||
log.info("*** Load/compile needed query implementations ***");
|
||||
QueryPreprocessor preprocessor;
|
||||
auto plan_paths = LoadFilePaths(path, "cpp");
|
||||
// query mark will be used to extract queries from files (because we want
|
||||
// to be independent to a query hash)
|
||||
auto query_mark = std::string("// Query: ");
|
||||
for (auto &plan_path : plan_paths)
|
||||
{
|
||||
auto lines = read_lines(plan_path);
|
||||
// find the line with a query in order
|
||||
// be able to place it in the dynamic libs container (base on query
|
||||
// hash)
|
||||
for (auto &line : lines)
|
||||
{
|
||||
// find query in the line
|
||||
auto pos = line.find(query_mark);
|
||||
// if query doesn't exist pass
|
||||
if (pos == std::string::npos) continue;
|
||||
auto query = trim(line.substr(pos + query_mark.size()));
|
||||
// load/compile implementations only for the queries which are
|
||||
// contained in queries_file
|
||||
// it doesn't make sense to compile something which won't be runned
|
||||
if (query_hashes.find(preprocessor.preprocess(query).hash) ==
|
||||
query_hashes.end())
|
||||
continue;
|
||||
log.info("Path {} will be loaded.", plan_path.c_str());
|
||||
engine.ReloadCustom(query, plan_path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
permanent_assert(query_hashes.size() == engine.Size(),
|
||||
"Query engine doesn't contain appropriate number of query "
|
||||
"implementations");
|
||||
}
|
||||
|
||||
/**
|
||||
* Executa all query plans in file on the path.
|
||||
*
|
||||
* @param log external logger reference
|
||||
* @param engine query engine
|
||||
* @param db a database agains the query plans are going to be executed
|
||||
* @param path path a queries file
|
||||
* @param stream used by query plans to output the results
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
auto ExecuteQueryPlans(Logger &log, QueryEngineT &engine, Db &db,
|
||||
const fs::path &path, StreamT &stream)
|
||||
{
|
||||
log.info("*** Execute the queries from the queries_file ***");
|
||||
// execute all queries from queries_file
|
||||
auto queries = utils::read_lines(path);
|
||||
for (auto &query : queries)
|
||||
{
|
||||
if (query.empty()) continue;
|
||||
permanent_assert(engine.Loaded(trim(query)),
|
||||
"Implementation wasn't loaded");
|
||||
engine.Run(query, db, stream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Warms Up the engine. Loads and executes query plans specified by the program
|
||||
* arguments:
|
||||
* -q -> a file with queries
|
||||
* -i -> a folder with query plans
|
||||
*
|
||||
* @param log external logger reference
|
||||
* @param engine query engine
|
||||
* @param db a database agains the query plans are going to be executed
|
||||
* @param stream used by query plans to output the results
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
auto WarmUpEngine(Logger &log, QueryEngineT &engine, Db &db, StreamT &stream)
|
||||
{
|
||||
// path to a file with queries
|
||||
auto queries_file = fs::path(
|
||||
GET_ARG("-q", "../data/queries/core/mg_basic_000.txt").get_string());
|
||||
// forlder with query implementations
|
||||
auto implementations_folder =
|
||||
fs::path(GET_ARG("-i", "../integration/hardcoded_query").get_string());
|
||||
|
||||
// load all query hashes from queries file
|
||||
auto query_hashes = LoadQueryHashes(log, queries_file);
|
||||
|
||||
// load compile all needed query plans
|
||||
LoadQueryPlans(log, engine, query_hashes, implementations_folder);
|
||||
|
||||
// execute all loaded query plasn
|
||||
ExecuteQueryPlans(log, engine, db, queries_file, stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,18 @@
|
||||
// TODO: refactor (backlog task)
|
||||
|
||||
#include <random>
|
||||
|
||||
#include "_hardcoded_query/basic.hpp"
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
#include "query/preprocesor.hpp"
|
||||
#include "query/strip/stripper.hpp"
|
||||
#include "query/preprocessor.hpp"
|
||||
#include "query/stripper.hpp"
|
||||
#include "storage/indexes/indexes.hpp"
|
||||
#include "utils/assert.hpp"
|
||||
#include "utils/signals/handler.hpp"
|
||||
#include "utils/stacktrace/log.hpp"
|
||||
#include "utils/sysinfo/memory.hpp"
|
||||
|
||||
QueryPreprocessor preprocessor;
|
||||
|
||||
// Returns uniform random size_t generator from range [0,n>
|
||||
auto rand_gen(size_t n)
|
||||
{
|
||||
@@ -24,6 +24,7 @@ auto rand_gen(size_t n)
|
||||
void run(size_t n, std::string &query, Db &db)
|
||||
{
|
||||
auto qf = hardcode::load_basic_functions(db);
|
||||
QueryPreprocessor preprocessor;
|
||||
auto stripped = preprocessor.preprocess(query);
|
||||
|
||||
logging::info("Running query {} [{}] x {}.", query, stripped.hash, n);
|
||||
@@ -42,6 +43,7 @@ void add_edge(size_t n, Db &db)
|
||||
std::string query = "MATCH (n1), (n2) WHERE ID(n1)=0 AND "
|
||||
"ID(n2)=1 CREATE (n1)<-[r:IS {age: "
|
||||
"25,weight: 70}]-(n2) RETURN r";
|
||||
QueryPreprocessor preprocessor;
|
||||
auto stripped = preprocessor.preprocess(query);
|
||||
|
||||
logging::info("Running query {} [{}] x {}.", query, stripped.hash, n);
|
||||
@@ -178,7 +180,7 @@ bool equal(Db &a, Db &b)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
logging::init_async();
|
||||
logging::init_sync();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
|
||||
SignalHandler::register_handler(Signal::SegmentationFault, []() {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
#include "utils/exceptions/not_yet_implemented.hpp"
|
||||
|
||||
@@ -21,27 +22,27 @@ public:
|
||||
|
||||
void write_success_empty()
|
||||
{
|
||||
stream << "SUCCESS EMPTY\n";
|
||||
stream << "SUCCESS EMPTY\n";
|
||||
}
|
||||
|
||||
void write_ignored()
|
||||
{
|
||||
stream << "IGNORED\n";
|
||||
stream << "IGNORED\n";
|
||||
}
|
||||
|
||||
void write_empty_fields()
|
||||
{
|
||||
stream << "EMPTY FIELDS\n";
|
||||
stream << "EMPTY FIELDS\n";
|
||||
}
|
||||
|
||||
void write_fields(const std::vector<std::string> &fields)
|
||||
{
|
||||
stream << "FIELDS:";
|
||||
for (auto &field : fields)
|
||||
{
|
||||
stream << " " << field;
|
||||
}
|
||||
stream << '\n';
|
||||
stream << "FIELDS:";
|
||||
for (auto &field : fields)
|
||||
{
|
||||
stream << " " << field;
|
||||
}
|
||||
stream << '\n';
|
||||
}
|
||||
|
||||
void write_field(const std::string &field)
|
||||
@@ -61,7 +62,7 @@ public:
|
||||
|
||||
void write_meta(const std::string &type)
|
||||
{
|
||||
stream << "Meta: " << type;
|
||||
stream << "Meta: " << type << std::endl;
|
||||
}
|
||||
|
||||
void write_failure(const std::map<std::string, std::string> &data)
|
||||
@@ -81,7 +82,8 @@ public:
|
||||
|
||||
void write_vertex_record(const VertexAccessor& va)
|
||||
{
|
||||
throw NotYetImplemented();
|
||||
va.stream_repr(stream);
|
||||
stream << std::endl;
|
||||
}
|
||||
|
||||
void write(const EdgeAccessor &edge)
|
||||
@@ -96,13 +98,11 @@ public:
|
||||
|
||||
void write(const StoredProperty<TypeGroupEdge> &prop)
|
||||
{
|
||||
// prop.accept(serializer);
|
||||
throw NotYetImplemented();
|
||||
}
|
||||
|
||||
void write(const StoredProperty<TypeGroupVertex> &prop)
|
||||
{
|
||||
// prop.accept(serializer);
|
||||
throw NotYetImplemented();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/**
|
||||
* DEPRICATED!
|
||||
*
|
||||
* TODO: print AST (just for one query) using Antlr's visitor or listener
|
||||
* the new file name should be opencypher_ast.cpp
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <vector>
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/**
|
||||
* DEPRICATED!
|
||||
*
|
||||
* TODO: remove once when Antlr will be integrated
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
|
||||
@@ -1,52 +1,72 @@
|
||||
#include <iostream>
|
||||
#include "../integration/query_engine_common.hpp"
|
||||
|
||||
#define DEBUG 1
|
||||
#include "utils/fswatcher.hpp"
|
||||
|
||||
#include "communication/communication.hpp"
|
||||
#include "query/language/cypher/common.hpp"
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
#include "query/engine.hpp"
|
||||
#include "utils/command_line/arguments.hpp"
|
||||
#include "utils/terminate_handler.hpp"
|
||||
#include "utils/time/timer.hpp"
|
||||
using namespace std::chrono_literals;
|
||||
using namespace tests::integration;
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::cin;
|
||||
|
||||
int main(void)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
std::set_terminate(&terminate_handler);
|
||||
// init arguments
|
||||
REGISTER_ARGS(argc, argv);
|
||||
|
||||
logging::init_sync();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
// forlder with query implementations
|
||||
auto implementations_folder = fs::path(
|
||||
GET_ARG("-i", "tests/integration/hardcoded_query").get_string());
|
||||
|
||||
// init engine
|
||||
auto log = init_logging("ManualQueryEngine");
|
||||
Db db;
|
||||
// TODO: write dummy socket that is going to execute test
|
||||
using stream_t = bolt::RecordStream<CoutSocket>;
|
||||
CoutSocket socket;
|
||||
stream_t stream(socket);
|
||||
QueryEngine<stream_t> engine;
|
||||
StreamT stream(std::cout);
|
||||
QueryEngineT query_engine;
|
||||
// IMPORTANT: PrintRecordStream can be replaces with a smarter
|
||||
// object that can test the results
|
||||
|
||||
cout << "-- Memgraph query engine --" << endl;
|
||||
WarmUpEngine(log, query_engine, db, stream);
|
||||
|
||||
while (true) {
|
||||
// read command
|
||||
cout << "> ";
|
||||
std::string command;
|
||||
std::getline(cin, command);
|
||||
if (command == "quit") break;
|
||||
// init watcher
|
||||
FSWatcher watcher;
|
||||
QueryPreprocessor preprocessor;
|
||||
|
||||
// execute command
|
||||
try {
|
||||
engine.execute(command, db, stream);
|
||||
} catch (const std::exception &e) {
|
||||
cout << e.what() << endl;
|
||||
} catch (const QueryEngineException &e) {
|
||||
cout << e.what() << endl;
|
||||
}
|
||||
}
|
||||
int i = 0;
|
||||
watcher.watch(
|
||||
WatchDescriptor(implementations_folder, FSEventType::CloseNowrite),
|
||||
[&](FSEvent event) {
|
||||
i++; // bacause only close_no_write could be detected and this
|
||||
// call will cause close no write again
|
||||
if (i % 2 == 1)
|
||||
{
|
||||
// take only cpp files
|
||||
if (event.path.extension() != ".cpp")
|
||||
return;
|
||||
|
||||
auto query_mark = std::string("// Query: ");
|
||||
auto lines = read_lines(event.path);
|
||||
for (auto &line : lines)
|
||||
{
|
||||
auto pos = line.find(query_mark);
|
||||
if (pos == std::string::npos) continue;
|
||||
auto query = line.substr(pos + query_mark.size());
|
||||
log.info("Reload: {}", query);
|
||||
query_engine.Unload(query);
|
||||
try {
|
||||
query_engine.ReloadCustom(query, event.path);
|
||||
query_engine.Run(query, db, stream);
|
||||
} catch (PlanCompilationException& e) {
|
||||
log.info("Query compilation failed: {}", e.what());
|
||||
} catch (std::exception& e) {
|
||||
log.info("Query execution failed: unknown reason");
|
||||
}
|
||||
log.info("Number of available query plans: {}", query_engine.Size());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: watcher for injected query
|
||||
|
||||
std::this_thread::sleep_for(1000s);
|
||||
|
||||
watcher.stop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
42
tests/manual/query_hash.cpp
Normal file
42
tests/manual/query_hash.cpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "query/language/cypher/common.hpp"
|
||||
#include "query/preprocessor.hpp"
|
||||
#include "utils/command_line/arguments.hpp"
|
||||
#include "utils/type_discovery.hpp"
|
||||
#include "utils/variadic/variadic.hpp"
|
||||
#include "utils/string/file.hpp"
|
||||
|
||||
using utils::println;
|
||||
|
||||
/**
|
||||
* Useful when somebody wants to get a hash for some query.
|
||||
*
|
||||
* Usage:
|
||||
* ./query_hash -q "CREATE (n {name: \"test\n"}) RETURN n"
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// init args
|
||||
REGISTER_ARGS(argc, argv);
|
||||
|
||||
// take query from input args
|
||||
auto query = GET_ARG("-q", "CREATE (n) RETURN n").get_string();
|
||||
|
||||
// run preprocessing
|
||||
QueryPreprocessor preprocessor;
|
||||
auto preprocessed = preprocessor.preprocess(query);
|
||||
|
||||
// print query, stripped query, hash and variable values (propertie values)
|
||||
println("Query: ", query);
|
||||
println("Stripped query: ", preprocessed.query);
|
||||
println("Query hash: ", preprocessed.hash);
|
||||
println("Property values:");
|
||||
for (auto property : preprocessed.arguments) {
|
||||
println(" ", property);
|
||||
}
|
||||
println("");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "query/language/cypher/common.hpp"
|
||||
#include "query/preprocesor.hpp"
|
||||
#include "utils/command_line/arguments.hpp"
|
||||
#include "utils/type_discovery.hpp"
|
||||
#include "utils/variadic/variadic.hpp"
|
||||
|
||||
using utils::println;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
// arguments parsing
|
||||
auto arguments = all_arguments(argc, argv);
|
||||
|
||||
// query extraction
|
||||
auto queries = extract_queries(arguments);
|
||||
|
||||
QueryPreprocessor preprocessor;
|
||||
|
||||
for (auto &query : queries)
|
||||
{
|
||||
auto preprocessed = preprocessor.preprocess(query);
|
||||
println("QUERY: ", query);
|
||||
println("STRIPPED QUERY: ", preprocessed.query);
|
||||
println("QUERY HASH: ", preprocessed.hash);
|
||||
println("PROPERTIES:");
|
||||
for (auto property : preprocessed.arguments) {
|
||||
println(" ", property);
|
||||
}
|
||||
println("-----------------------------");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user