better architecture for hardcoded test queries (still has to be polished)
This commit is contained in:
parent
8362b64e9f
commit
afc0a4a176
@ -593,6 +593,7 @@ if (MEMGRAPH)
|
||||
target_link_libraries(${MEMGRAPH_BUILD_NAME} memgraph)
|
||||
endif ()
|
||||
|
||||
target_link_libraries(${MEMGRAPH_BUILD_NAME} stdc++fs)
|
||||
target_link_libraries(${MEMGRAPH_BUILD_NAME} Threads::Threads)
|
||||
target_link_libraries(${MEMGRAPH_BUILD_NAME} cypher_lib)
|
||||
if (UNIX)
|
||||
|
@ -21,10 +21,11 @@ public:
|
||||
#else
|
||||
std::string template_path = CONFIG(config::TEMPLATE_CPU_CPP_PATH);
|
||||
#endif
|
||||
template_file = utils::read_file(template_path.c_str());
|
||||
template_text = utils::read_text(fs::path(template_path));
|
||||
}
|
||||
|
||||
template <typename Tree>
|
||||
// TODO: query and path shoud be distinct types
|
||||
void generate_code(const Tree &tree, const std::string &query,
|
||||
const uint64_t stripped_hash, const std::string &path)
|
||||
{
|
||||
@ -42,7 +43,7 @@ public:
|
||||
|
||||
// save the code
|
||||
std::string generated = template_engine::render(
|
||||
template_file, {{"class_name", "CodeCPU"},
|
||||
template_text.str(), {{"class_name", "CodeCPU"},
|
||||
{"stripped_hash", std::to_string(stripped_hash)},
|
||||
{"query", query},
|
||||
#ifdef BARRIER
|
||||
@ -54,12 +55,12 @@ public:
|
||||
|
||||
logger.trace("generated code: {}", generated);
|
||||
|
||||
utils::write_file(generated, path);
|
||||
utils::write(utils::Text(generated), fs::path(path));
|
||||
}
|
||||
|
||||
protected:
|
||||
Logger logger;
|
||||
|
||||
private:
|
||||
std::string template_file;
|
||||
utils::Text template_text;
|
||||
};
|
||||
|
@ -8,15 +8,24 @@ auto delete_query_action =
|
||||
|
||||
std::string code = "";
|
||||
|
||||
for (auto const &kv : action_data.actions) {
|
||||
// TODO: don't delete the whole graph
|
||||
|
||||
for (auto const &kv : action_data.actions)
|
||||
{
|
||||
auto entity = kv.first;
|
||||
if (kv.second == ClauseAction::DeleteNode && action_data.is_detach) {
|
||||
|
||||
if (kv.second == ClauseAction::DeleteNode && action_data.is_detach)
|
||||
{
|
||||
code += code_line(delete_whole_graph);
|
||||
}
|
||||
if (kv.second == ClauseAction::DeleteNode && !action_data.is_detach) {
|
||||
|
||||
if (kv.second == ClauseAction::DeleteNode && !action_data.is_detach)
|
||||
{
|
||||
code += code_line(delete_all_detached_nodes);
|
||||
}
|
||||
if (kv.second == ClauseAction::DeleteRelationship) {
|
||||
|
||||
if (kv.second == ClauseAction::DeleteRelationship)
|
||||
{
|
||||
code += code_line("// DELETE Relationship({})", entity);
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include "includes.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef BARRIER
|
||||
|
||||
#include "barrier/barrier.hpp"
|
||||
namespace barrier
|
||||
namespace hardcode
|
||||
{
|
||||
|
||||
#else
|
||||
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#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"
|
||||
#include "storage/edge_type/edge_type.hpp"
|
||||
#include "storage/edge_x_vertex.hpp"
|
||||
#include "storage/indexes/index_definition.hpp"
|
||||
#include "storage/label/label.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#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 "query/util.hpp"
|
||||
|
||||
#endif
|
||||
|
||||
auto load_queries(Db &db)
|
||||
auto load_basic_functions(Db &db)
|
||||
{
|
||||
std::map<uint64_t, std::function<bool(properties_t &&)>> queries;
|
||||
query_functions_t functions;
|
||||
|
||||
// CREATE (n {prop: 0}) RETURN n
|
||||
auto create_node = [&db](properties_t &&args) {
|
||||
@ -54,7 +17,7 @@ auto load_queries(Db &db)
|
||||
vertex_accessor.set(property_key, std::move(args[0]));
|
||||
return t.commit();
|
||||
};
|
||||
queries[11597417457737499503u] = create_node;
|
||||
functions[11597417457737499503u] = create_node;
|
||||
|
||||
// CREATE (n:LABEL {name: "TEST"}) RETURN n;
|
||||
auto create_labeled_and_named_node = [&db](properties_t &&args) {
|
||||
@ -490,45 +453,35 @@ auto load_queries(Db &db)
|
||||
return false;
|
||||
}
|
||||
};
|
||||
queries[17721584194272598838u] = match_label_property;
|
||||
functions[17721584194272598838u] = match_label_property;
|
||||
|
||||
// Blueprint:
|
||||
// auto = [&db](properties_t &&args) {
|
||||
// DbAccessor t(db);
|
||||
//
|
||||
//
|
||||
// return t.commit();
|
||||
// };
|
||||
|
||||
queries[15284086425088081497u] = match_all_nodes;
|
||||
queries[4857652843629217005u] = match_by_label;
|
||||
queries[15648836733456301916u] = create_edge_v2;
|
||||
queries[10597108978382323595u] = create_account;
|
||||
queries[5397556489557792025u] = create_labeled_and_named_node;
|
||||
functions[15284086425088081497u] = match_all_nodes;
|
||||
functions[4857652843629217005u] = match_by_label;
|
||||
functions[15648836733456301916u] = create_edge_v2;
|
||||
functions[10597108978382323595u] = create_account;
|
||||
functions[5397556489557792025u] = create_labeled_and_named_node;
|
||||
|
||||
// TODO: query hasher reports two hash values
|
||||
queries[998725786176032607u] = create_labeled_and_named_node_v2;
|
||||
queries[16090682663946456821u] = create_labeled_and_named_node_v2;
|
||||
functions[998725786176032607u] = create_labeled_and_named_node_v2;
|
||||
functions[16090682663946456821u] = create_labeled_and_named_node_v2;
|
||||
|
||||
queries[7939106225150551899u] = create_edge;
|
||||
queries[6579425155585886196u] = create_edge;
|
||||
queries[11198568396549106428u] = find_node_by_internal_id;
|
||||
queries[8320600413058284114u] = find_edge_by_internal_id;
|
||||
queries[6813335159006269041u] = update_node;
|
||||
queries[10506105811763742758u] = match_all_delete;
|
||||
queries[13742779491897528506u] = match_label_delete;
|
||||
queries[11349462498691305864u] = match_id_delete;
|
||||
queries[6963549500479100885u] = match_edge_id_delete;
|
||||
queries[14897166600223619735u] = match_edge_all_delete;
|
||||
queries[16888549834923624215u] = match_edge_type_delete;
|
||||
queries[11675960684124428508u] = match_id_type_return;
|
||||
queries[15698881472054193835u] = match_name_type_return;
|
||||
queries[12595102442911913761u] = match_name_type_return_cross;
|
||||
queries[8918221081398321263u] = match_label_type_return;
|
||||
functions[7939106225150551899u] = create_edge;
|
||||
functions[6579425155585886196u] = create_edge;
|
||||
functions[11198568396549106428u] = find_node_by_internal_id;
|
||||
functions[8320600413058284114u] = find_edge_by_internal_id;
|
||||
functions[6813335159006269041u] = update_node;
|
||||
functions[10506105811763742758u] = match_all_delete;
|
||||
functions[13742779491897528506u] = match_label_delete;
|
||||
functions[11349462498691305864u] = match_id_delete;
|
||||
functions[6963549500479100885u] = match_edge_id_delete;
|
||||
functions[14897166600223619735u] = match_edge_all_delete;
|
||||
functions[16888549834923624215u] = match_edge_type_delete;
|
||||
functions[11675960684124428508u] = match_id_type_return;
|
||||
functions[15698881472054193835u] = match_name_type_return;
|
||||
functions[12595102442911913761u] = match_name_type_return_cross;
|
||||
functions[8918221081398321263u] = match_label_type_return;
|
||||
|
||||
return queries;
|
||||
return functions;
|
||||
}
|
||||
|
||||
#ifdef BARRIER
|
||||
}
|
||||
#endif
|
123
include/query/hardcode/dressipi.hpp
Normal file
123
include/query/hardcode/dressipi.hpp
Normal file
@ -0,0 +1,123 @@
|
||||
#pragma once
|
||||
|
||||
#include "includes.hpp"
|
||||
|
||||
namespace hardcode
|
||||
{
|
||||
|
||||
// TODO: decouple hashes from the code because hashes could and should be
|
||||
// tested separately
|
||||
|
||||
auto load_dressipi_functions(Db &db)
|
||||
{
|
||||
query_functions_t functions;
|
||||
|
||||
// Query: CREATE (n {garment_id: 1234, garment_category_id: 1}) RETURN n
|
||||
// Hash: 12139093029838549530
|
||||
functions[12139093029838549530u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: CREATE (p:profile {profile_id: 111, partner_id: 55}) RETURN p
|
||||
// Hash: 17158428452166262783
|
||||
functions[17158428452166262783u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (g:garment {garment_id: 1234}) SET g:FF RETURN labels(g)
|
||||
// Hash: 11123780635391515946
|
||||
functions[11123780635391515946u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// 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
|
||||
functions[674581607834128909u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (g:garment {garment_id: 3456}) SET g.reveals = 50 RETURN g
|
||||
// Hash: 2839969099736071844
|
||||
functions[2839969099736071844u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MERGE (g1:garment {garment_id: 1234})-[r:default_outfit]-(g2:garment {garment_id: 2345}) RETURN r
|
||||
// Hash: 3782642357973971504
|
||||
functions[3782642357973971504u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// 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
|
||||
functions[7871009397157280694u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (p:profile {profile_id: 111, partner_id: 55})-[s:score]-(g.garment {garment_id: 1234}) DELETE s
|
||||
// Hash: 9459600951073026137
|
||||
functions[9459600951073026137u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (p:profile {profile_id: 113}) DELETE p
|
||||
// Hash: 6763665709953344106
|
||||
functions[6763665709953344106u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (n) DETACH DELETE n
|
||||
// Hash: 4798158026600988079
|
||||
functions[4798158026600988079u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (p:profile) RETURN p
|
||||
// Hash: 15599970964909894866
|
||||
functions[15599970964909894866u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (g:garment) RETURN COUNT(g)
|
||||
// Hash: 11458306387621940265
|
||||
functions[11458306387621940265u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (g:garment {garment_id: 1234}) RETURN g
|
||||
// Hash: 7756609649964321221
|
||||
functions[7756609649964321221u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (p:profile {partner_id: 55}) RETURN p
|
||||
// Hash: 17506488413143988006
|
||||
functions[17506488413143988006u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
// Query: MATCH (n) RETURN count(n)
|
||||
// Hash: 10510787599699014973
|
||||
functions[10510787599699014973u] = [&db](properties_t &&args) {
|
||||
DbAccessor t(db);
|
||||
return t.commit();
|
||||
};
|
||||
|
||||
return functions;
|
||||
}
|
||||
|
||||
}
|
38
include/query/hardcode/includes.hpp
Normal file
38
include/query/hardcode/includes.hpp
Normal file
@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <map>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#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"
|
||||
#include "query/util.hpp"
|
||||
#include "storage/edge_type/edge_type.hpp"
|
||||
#include "storage/edge_x_vertex.hpp"
|
||||
#include "storage/indexes/index_definition.hpp"
|
||||
#include "storage/label/label.hpp"
|
||||
#include "storage/model/properties/all.hpp"
|
||||
#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"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace hardcode
|
||||
{
|
||||
using query_functions_t =
|
||||
std::map<uint64_t, std::function<bool(properties_t &&)>>;
|
||||
}
|
@ -20,3 +20,4 @@
|
||||
#include "expr.hpp"
|
||||
#include "with.hpp"
|
||||
#include "functions.hpp"
|
||||
#include "merge.hpp"
|
||||
|
@ -55,6 +55,7 @@ struct ReturnList;
|
||||
struct Distinct;
|
||||
|
||||
struct Create;
|
||||
struct Merge;
|
||||
struct Match;
|
||||
struct Where;
|
||||
struct Set;
|
||||
@ -66,6 +67,7 @@ struct ReadQuery;
|
||||
struct UpdateQuery;
|
||||
struct DeleteQuery;
|
||||
struct ReadWriteQuery;
|
||||
struct MergeQuery;
|
||||
|
||||
struct SetKey;
|
||||
struct SetValue;
|
||||
@ -89,7 +91,7 @@ struct AstVisitor
|
||||
Return, Distinct, Delete, DeleteQuery, UpdateQuery, Set, SetKey,
|
||||
ReadWriteQuery, IdentifierList, WithList, WithClause, WithQuery, Long,
|
||||
CountFunction, LabelsFunction, InternalIdExpr, SetValue, SetElement,
|
||||
LabelSetElement, SetList>
|
||||
MergeQuery, Merge, LabelSetElement, SetList>
|
||||
{
|
||||
};
|
||||
}
|
||||
|
18
include/query/language/cypher/ast/merge.hpp
Normal file
18
include/query/language/cypher/ast/merge.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "ast_node.hpp"
|
||||
#include "pattern.hpp"
|
||||
#include "return.hpp"
|
||||
|
||||
namespace ast
|
||||
{
|
||||
|
||||
struct Merge : public AstNode<Merge>
|
||||
{
|
||||
Merge(Pattern* pattern)
|
||||
: pattern(pattern) {}
|
||||
|
||||
Pattern* pattern;
|
||||
};
|
||||
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
#include "match.hpp"
|
||||
#include "return.hpp"
|
||||
#include "set.hpp"
|
||||
#include "merge.hpp"
|
||||
|
||||
namespace ast
|
||||
{
|
||||
@ -70,4 +71,17 @@ struct ReadWriteQuery : public AstNode<ReadWriteQuery>
|
||||
Return *return_clause;
|
||||
};
|
||||
|
||||
struct MergeQuery : public AstNode<MergeQuery>
|
||||
{
|
||||
MergeQuery(Merge* merge_clause, Set* set_clause, Return* return_clause) :
|
||||
merge_clause(merge_clause), set_clause(set_clause),
|
||||
return_clause(return_clause)
|
||||
{
|
||||
}
|
||||
|
||||
Merge *merge_clause;
|
||||
Set *set_clause;
|
||||
Return *return_clause;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,15 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "utils/command_line/arguments.hpp"
|
||||
#include "utils/string/file.hpp"
|
||||
|
||||
std::string extract_query(const std::vector<std::string>& arguments)
|
||||
auto extract_queries(const std::vector<std::string>& arguments)
|
||||
{
|
||||
std::vector<std::string> queries;
|
||||
|
||||
// load single query
|
||||
if (contains_argument(arguments, "-q"))
|
||||
return get_argument(arguments, "-q", "CREATE (n) RETURN n");
|
||||
auto default_file = "query.cypher";
|
||||
{
|
||||
queries.emplace_back(get_argument(arguments, "-q", "CREATE (n) RETURN n"));
|
||||
return queries;
|
||||
}
|
||||
|
||||
// load multiple queries from file
|
||||
auto default_file = "queries.cypher";
|
||||
auto file = get_argument(arguments, "-f", default_file);
|
||||
// TODO: error handling
|
||||
return utils::read_file(file.c_str());
|
||||
return utils::read_lines(file.c_str());
|
||||
}
|
||||
|
||||
|
@ -81,6 +81,22 @@ start ::= read_write_query(Q). {
|
||||
ast->root = Q;
|
||||
}
|
||||
|
||||
start ::= merge_query(Q). {
|
||||
ast->root = Q;
|
||||
}
|
||||
|
||||
// -- merge query
|
||||
|
||||
%type merge_query {ast::MergeQuery*}
|
||||
|
||||
merge_query(MQ) ::= merge_clause(MC) set_clause(SC) return_clause(RC). {
|
||||
MQ = ast->create<ast::MergeQuery>(MC, SC, RC);
|
||||
}
|
||||
|
||||
merge_query(MQ) ::= merge_clause(MC) return_clause(RC). {
|
||||
MQ = ast->create<ast::MergeQuery>(MC, nullptr, RC);
|
||||
}
|
||||
|
||||
// -- with query
|
||||
|
||||
%type with_query {ast::WithQuery*}
|
||||
@ -188,7 +204,13 @@ delete_query(DQ) ::= match_clause(M) delete_clause(D). {
|
||||
%type create_clause {ast::Create*}
|
||||
|
||||
create_clause(C) ::= CREATE pattern(P). {
|
||||
C = ast->create<ast::Create>(P);
|
||||
C = ast->create<ast::Create>(P);
|
||||
}
|
||||
|
||||
%type merge_clause {ast::Merge*}
|
||||
|
||||
merge_clause(M) ::= MERGE pattern(P). {
|
||||
M = ast->create<ast::Merge>(P);
|
||||
}
|
||||
|
||||
%type match_clause {ast::Match*}
|
||||
|
@ -350,6 +350,12 @@ public:
|
||||
Traverser::visit(write_query);
|
||||
}
|
||||
|
||||
void visit(ast::MergeQuery &merge_query) override
|
||||
{
|
||||
auto entry = printer.advance("Merge Query");
|
||||
Traverser::visit(merge_query);
|
||||
}
|
||||
|
||||
void visit(ast::DeleteQuery &delete_query) override
|
||||
{
|
||||
auto entry = printer.advance("Delete Query");
|
||||
@ -371,6 +377,12 @@ public:
|
||||
Traverser::visit(create);
|
||||
}
|
||||
|
||||
void visit(ast::Merge &merge) override
|
||||
{
|
||||
auto entry = printer.advance("Merge");
|
||||
Traverser::visit(merge);
|
||||
}
|
||||
|
||||
void visit(ast::UpdateQuery &update_query) override
|
||||
{
|
||||
auto entry = printer.advance("Update Query");
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
|
||||
// keywords
|
||||
rule("(?i:CREATE)", TK_CREATE);
|
||||
rule("(?i:MERGE)", TK_MERGE);
|
||||
rule("(?i:MATCH)", TK_MATCH);
|
||||
rule("(?i:WHERE)", TK_WHERE);
|
||||
rule("(?i:SET)", TK_SET);
|
||||
|
@ -34,6 +34,13 @@ public:
|
||||
accept(query.return_clause);
|
||||
}
|
||||
|
||||
void visit(ast::MergeQuery& query) override
|
||||
{
|
||||
accept(query.merge_clause);
|
||||
accept(query.set_clause);
|
||||
accept(query.return_clause);
|
||||
}
|
||||
|
||||
void visit(ast::Match& match) override
|
||||
{
|
||||
accept(match.pattern_list);
|
||||
@ -261,6 +268,11 @@ public:
|
||||
accept(create.pattern);
|
||||
}
|
||||
|
||||
void visit(ast::Merge& merge) override
|
||||
{
|
||||
accept(merge.pattern);
|
||||
}
|
||||
|
||||
void visit(ast::Distinct& distinct) override
|
||||
{
|
||||
accept(distinct.identifier);
|
||||
|
@ -27,5 +27,10 @@ public:
|
||||
auto preprocess(const std::string &query) { return stripper.strip(query); }
|
||||
|
||||
private:
|
||||
// In C++17 the ints should be unnecessary?
|
||||
// as far as I understand in C++17 class template parameters
|
||||
// can be deduced just like function template parameters
|
||||
// TODO: once C++ 17 will be well suported by comilers
|
||||
// refactor this piece of code
|
||||
QueryStripper<int, int, int, int> stripper;
|
||||
};
|
||||
|
@ -26,7 +26,8 @@ template <typename... Ts>
|
||||
class QueryStripper : public Loggable
|
||||
{
|
||||
public:
|
||||
QueryStripper(Ts &&... strip_types) : Loggable("QueryStripper"),
|
||||
QueryStripper(Ts &&... strip_types)
|
||||
: Loggable("QueryStripper"),
|
||||
strip_types(std::make_tuple(std::forward<Ts>(strip_types)...)),
|
||||
lexer(std::make_unique<CypherLexer>())
|
||||
{
|
||||
@ -34,19 +35,21 @@ public:
|
||||
|
||||
QueryStripper(QueryStripper &other) = delete;
|
||||
|
||||
QueryStripper(QueryStripper &&other) : Loggable("QueryStripper"),
|
||||
strip_types(std::move(other.strip_types)),
|
||||
QueryStripper(QueryStripper &&other)
|
||||
: Loggable("QueryStripper"), strip_types(std::move(other.strip_types)),
|
||||
lexer(std::move(other.lexer))
|
||||
{
|
||||
}
|
||||
|
||||
auto strip_space(const std::string &query)
|
||||
{
|
||||
return strip(query, " ");
|
||||
}
|
||||
auto strip_space(const std::string &query) { return strip(query, " "); }
|
||||
|
||||
auto strip(const std::string &query, const std::string &separator = "")
|
||||
{
|
||||
// -------------------------------------------------------------------
|
||||
// TODO: write speed tests and then optimize, because this
|
||||
// function is called before every query execution !
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// TODO write this more optimal (resplace string
|
||||
// concatenation with something smarter)
|
||||
// TODO: in place substring replacement
|
||||
@ -66,7 +69,8 @@ public:
|
||||
if (_or(token.id, strip_types, std::make_index_sequence<size>{}))
|
||||
{
|
||||
auto index = counter++;
|
||||
switch (token.id) {
|
||||
switch (token.id)
|
||||
{
|
||||
case TK_LONG:
|
||||
store_query_param<Int64>(stripped_arguments,
|
||||
std::stol(token.value));
|
||||
@ -78,7 +82,8 @@ public:
|
||||
// TODO: remove
|
||||
store_query_param<String>(stripped_arguments, token.value);
|
||||
break;
|
||||
case TK_BOOL: {
|
||||
case TK_BOOL:
|
||||
{
|
||||
bool value = token.value[0] == 'T' || token.value[0] == 't';
|
||||
store_query_param<Bool>(stripped_arguments, value);
|
||||
break;
|
||||
@ -92,16 +97,33 @@ public:
|
||||
assert(false);
|
||||
}
|
||||
stripped_query += std::to_string(index) + separator;
|
||||
} else {
|
||||
// TODO: lowercase only keywords like (MATCH, CREATE, ...)
|
||||
}
|
||||
else
|
||||
{
|
||||
// if token is keyword then lowercase because query hash
|
||||
// should be the same
|
||||
// TODO: probably we shoud do the lowercase before
|
||||
// or during the tokenization (SPEED TESTS)
|
||||
if (token.id == TK_OR || token.id == TK_AND ||
|
||||
token.id == TK_NOT || token.id == TK_WITH ||
|
||||
token.id == TK_SET || token.id == TK_CREATE ||
|
||||
token.id == TK_MERGE || token.id == TK_MATCH ||
|
||||
token.id == TK_DELETE || token.id == TK_DETACH ||
|
||||
token.id == TK_WHERE || token.id == TK_RETURN ||
|
||||
token.id == TK_DISTINCT || token.id == TK_COUNT ||
|
||||
token.id == TK_LABELS)
|
||||
{
|
||||
std::transform(token.value.begin(), token.value.end(),
|
||||
token.value.begin(), ::tolower);
|
||||
}
|
||||
stripped_query += token.value + separator;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: hash function should be a template parameter
|
||||
auto hash = fnv(stripped_query);
|
||||
return QueryStripped(std::move(stripped_query),
|
||||
std::move(stripped_arguments),
|
||||
hash);
|
||||
std::move(stripped_arguments), hash);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -111,7 +133,7 @@ private:
|
||||
template <typename Value, typename Tuple, std::size_t... index>
|
||||
bool _or(Value &&value, Tuple &&tuple, std::index_sequence<index...>)
|
||||
{
|
||||
return or_vargs(std::forward<Value>(value),
|
||||
return utils::or_vargs(std::forward<Value>(value),
|
||||
std::get<index>(std::forward<Tuple>(tuple))...);
|
||||
}
|
||||
};
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <stdexcept>
|
||||
#include <cstdlib>
|
||||
|
||||
// TODO: isolate from caller (caller should know that his dependency is
|
||||
// TODO: isolate from caller (caller shouldn't know that his dependency is)
|
||||
// yaml-cpp
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
@ -50,6 +50,10 @@ public:
|
||||
return config;
|
||||
}
|
||||
|
||||
void register_program_arguments()
|
||||
{
|
||||
}
|
||||
|
||||
std::string operator[](const char* key)
|
||||
{
|
||||
return _config[key].template as<std::string>();
|
||||
|
@ -1,19 +1,66 @@
|
||||
#pragma once
|
||||
|
||||
#include <cerrno>
|
||||
// TODO: remove experimental from here once that becomes possible
|
||||
#include <experimental/filesystem>
|
||||
#include <fstream>
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
#include <cerrno>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
// TODO: remove experimental from here once it becomes possible
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
namespace utils
|
||||
{
|
||||
|
||||
std::string read_file(const char *filename);
|
||||
/*
|
||||
* Type safe text object.
|
||||
*/
|
||||
class Text
|
||||
{
|
||||
public:
|
||||
Text() = default;
|
||||
explicit Text(const std::string &text) : text_(text) {}
|
||||
|
||||
void write_file(const std::string& content, const std::string& path);
|
||||
// text could be huge and copy operationt would be too expensive
|
||||
Text(const Text& other) = delete;
|
||||
Text& operator=(const Text& other) = delete;
|
||||
|
||||
// the object is movable
|
||||
Text (Text&& other) = default;
|
||||
Text& operator=(Text&& other)
|
||||
{
|
||||
text_ = std::move(other.text_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::string &str() const { return text_; }
|
||||
|
||||
private:
|
||||
std::string text_;
|
||||
};
|
||||
|
||||
/*
|
||||
* Reads the whole text from a file at the path.
|
||||
*/
|
||||
Text read_text(const fs::path &path);
|
||||
|
||||
/*
|
||||
* Reads all the lines from a file at the path.
|
||||
*/
|
||||
std::vector<std::string> read_lines(const fs::path &path);
|
||||
|
||||
// TODO: lazy implementation of read_lines functionality (line by line)
|
||||
|
||||
// TODO: read word by word + lazy implementation
|
||||
|
||||
/*
|
||||
* Write text in a file at the path.
|
||||
*/
|
||||
void write(const Text &text, const fs::path &path);
|
||||
|
||||
}
|
||||
|
@ -2,23 +2,38 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// variadic argument printer
|
||||
namespace utils
|
||||
{
|
||||
|
||||
/*
|
||||
* Variadic argument print
|
||||
*/
|
||||
template<class Head>
|
||||
void _print_vargs(std::ostream& s, Head&& head)
|
||||
void print_vargs(std::ostream& s, Head&& head)
|
||||
{
|
||||
s << std::forward<Head>(head);
|
||||
}
|
||||
template<class Head, class ...Tail>
|
||||
void _print_vargs(std::ostream& s, Head&& head, Tail&& ...tail)
|
||||
void print_vargs(std::ostream& s, Head&& head, Tail&& ...tail)
|
||||
{
|
||||
s << std::forward<Head>(head);
|
||||
_print_vargs(s, std::forward<Tail>(tail)...);
|
||||
print_vargs(s, std::forward<Tail>(tail)...);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile time print line.
|
||||
*
|
||||
* USAGE:
|
||||
* RUN: utils::printer("ONE ", "TWO");
|
||||
* OUTPUT: "ONE TWO\n"
|
||||
*
|
||||
* TODO: reimplament with C++17 fold expressions
|
||||
*/
|
||||
template<class ...Args>
|
||||
void print_vargs(Args&&... args)
|
||||
void println(Args&&... args)
|
||||
{
|
||||
_print_vargs(std::cout, std::forward<Args>(args)...);
|
||||
print_vargs(std::cout, std::forward<Args>(args)...);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
// value equality with any of variadic argument
|
||||
@ -39,3 +54,5 @@ bool or_vargs(Value&& value, Array&&... array)
|
||||
{
|
||||
return _or_vargs(std::forward<Value>(value), std::forward<Array>(array)...);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,25 +1,43 @@
|
||||
#include "utils/string/file.hpp"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
|
||||
std::string read_file(const char *filename)
|
||||
namespace fs = std::experimental::filesystem;
|
||||
|
||||
Text read_text(const fs::path &path)
|
||||
{
|
||||
std::ifstream in(filename, std::ios::in | std::ios::binary);
|
||||
std::ifstream in(path, std::ios::in | std::ios::binary);
|
||||
|
||||
if (in)
|
||||
return std::string(std::istreambuf_iterator<char>(in),
|
||||
std::istreambuf_iterator<char>());
|
||||
return Text(std::string(std::istreambuf_iterator<char>(in),
|
||||
std::istreambuf_iterator<char>()));
|
||||
|
||||
auto error_message = fmt::format("{0}{1}", "Fail to read: ", filename);
|
||||
auto error_message = fmt::format("{0}{1}", "Fail to read: ", path.c_str());
|
||||
throw std::runtime_error(error_message);
|
||||
}
|
||||
|
||||
void write_file(const std::string& content, const std::string& path)
|
||||
std::vector<std::string> read_lines(const fs::path &path)
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
|
||||
std::ifstream stream(path.c_str());
|
||||
std::string line;
|
||||
while (std::getline(stream, line))
|
||||
{
|
||||
lines.emplace_back(line);
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
void write(const Text &text, const fs::path &path)
|
||||
{
|
||||
std::ofstream stream;
|
||||
stream.open(path.c_str());
|
||||
stream << content;
|
||||
stream << text.str();
|
||||
stream.close();
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,7 @@ endforeach()
|
||||
|
||||
# test hard coded queries
|
||||
add_executable(integration_queries integration/queries.cpp)
|
||||
target_link_libraries(integration_queries stdc++fs)
|
||||
target_link_libraries(integration_queries memgraph)
|
||||
target_link_libraries(integration_queries Threads::Threads)
|
||||
target_link_libraries(integration_queries ${fmt_static_lib})
|
||||
@ -102,6 +103,7 @@ set_property(TARGET index PROPERTY CXX_STANDARD 14)
|
||||
|
||||
# cypher_ast
|
||||
add_executable(manual_cypher_ast manual/cypher_ast.cpp)
|
||||
target_link_libraries(manual_cypher_ast stdc++fs)
|
||||
target_link_libraries(manual_cypher_ast memgraph)
|
||||
target_link_libraries(manual_cypher_ast Threads::Threads)
|
||||
target_link_libraries(manual_cypher_ast ${fmt_static_lib})
|
||||
@ -120,6 +122,7 @@ set_property(TARGET manual_queries PROPERTY CXX_STANDARD 14)
|
||||
|
||||
# query_engine
|
||||
add_executable(manual_query_engine manual/query_engine.cpp)
|
||||
target_link_libraries(manual_query_engine stdc++fs)
|
||||
target_link_libraries(manual_query_engine memgraph)
|
||||
target_link_libraries(manual_query_engine ${fmt_static_lib})
|
||||
target_link_libraries(manual_query_engine ${yaml_static_lib})
|
||||
@ -130,6 +133,7 @@ set_property(TARGET manual_query_engine PROPERTY CXX_STANDARD 14)
|
||||
|
||||
# query_hasher
|
||||
add_executable(manual_query_hasher manual/query_hasher.cpp)
|
||||
target_link_libraries(manual_query_hasher stdc++fs)
|
||||
target_link_libraries(manual_query_hasher memgraph)
|
||||
target_link_libraries(manual_query_hasher ${fmt_static_lib})
|
||||
target_link_libraries(manual_query_hasher ${yaml_static_lib})
|
||||
|
27
tests/data/queries/core/basic.txt
Normal file
27
tests/data/queries/core/basic.txt
Normal file
@ -0,0 +1,27 @@
|
||||
CREATE (n:LABEL {name: "TEST01"}) RETURN n
|
||||
CREATE (n:LABEL {name: "TEST02"}) RETURN n
|
||||
CREATE (n:LABEL {name: "TEST2"}) RETURN n
|
||||
CREATE (n:LABEL {name: "TEST3"}) RETURN n
|
||||
CREATE (n:OTHER {name: "TEST4"}) RETURN n
|
||||
CREATE (n:ACCOUNT {id: 2322, name: "TEST", country: "Croatia", "created_at": 2352352}) RETURN n
|
||||
MATCH (n {id: 0}) RETURN n", "MATCH (n {id: 1}) RETURN n
|
||||
MATCH (n {id: 2}) RETURN n", "MATCH (n {id: 3}) RETURN n
|
||||
MATCH (a {id:0}), (p {id: 1}) CREATE (a)-[r:IS]->(p) RETURN r
|
||||
MATCH (a {id:1}), (p {id: 2}) CREATE (a)-[r:IS]->(p) RETURN r
|
||||
MATCH ()-[r]-() WHERE ID(r)=0 RETURN r
|
||||
MATCH ()-[r]-() WHERE ID(r)=1 RETURN r
|
||||
MATCH (n: {id: 0}) SET n.name = "TEST100" RETURN n
|
||||
MATCH (n: {id: 1}) SET n.name = "TEST101" RETURN n
|
||||
MATCH (n: {id: 0}) SET n.name = "TEST102" RETURN n
|
||||
MATCH (n:LABEL) RETURN n"
|
||||
MATCH (n1), (n2) WHERE ID(n1)=0 AND ID(n2)=1 CREATE (n1)<-[r:IS {age: 25,weight: 70}]-(n2) RETURN r
|
||||
MATCH (n) RETURN n", "MATCH (n:LABEL) RETURN n", "MATCH (n) DELETE n
|
||||
MATCH (n:LABEL) DELETE n", "MATCH (n) WHERE ID(n) = 0 DELETE n
|
||||
MATCH ()-[r]-() WHERE ID(r) = 0 DELETE r", "MATCH ()-[r]-() DELETE r
|
||||
MATCH ()-[r:TYPE]-() DELETE r
|
||||
MATCH (n)-[:TYPE]->(m) WHERE ID(n) = 0 RETURN m
|
||||
MATCH (n)-[:TYPE]->(m) WHERE n.name = "kruno" RETURN m
|
||||
MATCH (n)-[:TYPE]->(m) WHERE n.name = "kruno" RETURN n,m
|
||||
MATCH (n:LABEL)-[:TYPE]->(m) RETURN n"
|
||||
CREATE (n:LABEL1:LABEL2 {name: "TEST01", age: 20}) RETURN n
|
||||
MATCH (n:LABEL1:LABEL2 {name: "TEST01", age: 20}) RETURN n
|
15
tests/data/queries/core/dressipi.txt
Normal file
15
tests/data/queries/core/dressipi.txt
Normal file
@ -0,0 +1,15 @@
|
||||
CREATE (n {garment_id: 1234, garment_category_id: 1}) RETURN n
|
||||
CREATE (p:profile {profile_id: 111, partner_id: 55}) RETURN p
|
||||
MATCH (g:garment {garment_id: 1234}) SET g:FF RETURN labels(g)
|
||||
MATCH (p:profile {profile_id: 111, partner_id: 55})-[s:score]-(g:garment{garment_id: 1234}) SET s.score = 1550 RETURN s.score
|
||||
MATCH (g:garment {garment_id: 3456}) SET g.reveals = 50 RETURN g
|
||||
MERGE (g1:garment {garment_id: 1234})-[r:default_outfit]-(g2:garment {garment_id: 2345}) RETURN r
|
||||
MERGE (p:profile {profile_id: 111, partner_id: 55})-[s:score]-(g.garment {garment_id: 1234}) SET s.score=1500 RETURN s
|
||||
MATCH (p:profile {profile_id: 111, partner_id: 55})-[s:score]-(g.garment {garment_id: 1234}) DELETE s
|
||||
MATCH (p:profile {profile_id: 113}) DELETE p
|
||||
MATCH (n) DETACH DELETE n
|
||||
MATCH (p:profile) RETURN p
|
||||
MATCH (g:garment) RETURN COUNT(g)
|
||||
MATCH (g:garment {garment_id: 1234}) RETURN g
|
||||
MATCH (p:profile {partner_id: 55}) RETURN p
|
||||
MATCH (n) RETURN count(n)
|
0
tests/data/queries/opencypher/dummy.txt
Normal file
0
tests/data/queries/opencypher/dummy.txt
Normal file
@ -1,11 +1,6 @@
|
||||
#include "query/hardcode/queries.hpp"
|
||||
|
||||
#ifdef BARRIER
|
||||
#include "barrier/barrier.cpp"
|
||||
#endif
|
||||
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
#include "query/hardcode/basic.hpp"
|
||||
#include "query/strip/stripper.hpp"
|
||||
#include "utils/sysinfo/memory.hpp"
|
||||
|
||||
@ -15,7 +10,8 @@ void run(size_t n, std::string &query, S &stripper, Q &qf)
|
||||
auto stripped = stripper.strip(query);
|
||||
std::cout << "Running query [" << stripped.hash << "] for " << n << " time."
|
||||
<< std::endl;
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
properties_t vec = stripped.arguments;
|
||||
assert(qf[stripped.hash](std::move(vec)));
|
||||
}
|
||||
@ -37,11 +33,7 @@ int main(void)
|
||||
|
||||
Db db("cleaning");
|
||||
|
||||
#ifdef BARRIER
|
||||
auto query_functions = load_queries(barrier::trans(db));
|
||||
#else
|
||||
auto query_functions = load_queries(db);
|
||||
#endif
|
||||
auto query_functions = hardcode::load_basic_functions(db);
|
||||
|
||||
auto stripper = make_query_stripper(TK_LONG, TK_FLOAT, TK_STR, TK_BOOL);
|
||||
|
||||
@ -50,7 +42,7 @@ int main(void)
|
||||
std::string create_vertex_other =
|
||||
"CREATE (n:OTHER {name: \"cleaner_test\"}) RETURN n";
|
||||
std::string delete_label_vertices = "MATCH (n:LABEL) DELETE n";
|
||||
std::string delete_all_vertices = "MATCH (n) DELETE n";
|
||||
std::string delete_all_vertices = "MATCH (n) DELETE n";
|
||||
|
||||
// ******************************* TEST 1 ********************************//
|
||||
// add vertices a
|
||||
|
@ -1,11 +1,6 @@
|
||||
#include "query/hardcode/queries.hpp"
|
||||
|
||||
#include <random>
|
||||
|
||||
#ifdef BARRIER
|
||||
#include "barrier/barrier.cpp"
|
||||
#endif
|
||||
|
||||
#include "query/hardcode/basic.hpp"
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
#include "query/strip/stripper.hpp"
|
||||
@ -24,11 +19,7 @@ void run(size_t n, std::string &query, Db &db)
|
||||
{
|
||||
auto stripper = make_query_stripper(TK_LONG, TK_FLOAT, TK_STR, TK_BOOL);
|
||||
|
||||
#ifdef BARRIER
|
||||
auto qf = load_queries(barrier::trans(db));
|
||||
#else
|
||||
auto qf = load_queries(db);
|
||||
#endif
|
||||
auto qf = hardcode::load_basic_functions(db);
|
||||
|
||||
auto stripped = stripper.strip(query);
|
||||
std::cout << "Running query [" << stripped.hash << "] for " << n << " time."
|
||||
@ -43,11 +34,7 @@ void add_edge(size_t n, Db &db)
|
||||
{
|
||||
auto stripper = make_query_stripper(TK_LONG, TK_FLOAT, TK_STR, TK_BOOL);
|
||||
|
||||
#ifdef BARRIER
|
||||
auto qf = load_queries(barrier::trans(db));
|
||||
#else
|
||||
auto qf = load_queries(db);
|
||||
#endif
|
||||
auto qf = hardcode::load_basic_functions(db);
|
||||
|
||||
std::string query = "MATCH (n1), (n2) WHERE ID(n1)=0 AND "
|
||||
"ID(n2)=1 CREATE (n1)<-[r:IS {age: "
|
||||
|
@ -1,76 +1,60 @@
|
||||
#include "query/hardcode/queries.hpp"
|
||||
|
||||
#ifdef BARRIER
|
||||
#include "barrier/barrier.cpp"
|
||||
#endif
|
||||
|
||||
#include "communication/bolt/v1/serialization/bolt_serializer.hpp"
|
||||
#include "database/db.hpp"
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
#include "query/hardcode/basic.hpp"
|
||||
#include "query/hardcode/dressipi.hpp"
|
||||
#include "query/strip/stripper.hpp"
|
||||
#include "utils/string/file.hpp"
|
||||
#include "utils/variadic/variadic.hpp"
|
||||
#include "utils/command_line/arguments.hpp"
|
||||
|
||||
int main(void)
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
auto arguments = all_arguments(argc, argv);
|
||||
|
||||
// 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");
|
||||
|
||||
// init logging
|
||||
logging::init_async();
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
|
||||
// init db, functions and stripper
|
||||
Db db;
|
||||
|
||||
#ifdef BARRIER
|
||||
auto query_functions = load_queries(barrier::trans(db));
|
||||
#else
|
||||
auto query_functions = load_queries(db);
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
// TODO: put all queries into a file
|
||||
std::vector<std::string> queries = {
|
||||
// load quries
|
||||
std::string file_path = "data/queries/core/" + suite_name + ".txt";
|
||||
auto queries = utils::read_lines(file_path.c_str());
|
||||
|
||||
// CREATE and MATCH by label and property
|
||||
"CREATE (n:LABEL {name: \"TEST01\"}) RETURN n",
|
||||
"CREATE (n:LABEL {name: \"TEST02\"}) RETURN n",
|
||||
// "MATCH (n:LABEL {name: \"TEST01\"}) RETURN n",
|
||||
// execute all queries
|
||||
for (auto &query : queries)
|
||||
{
|
||||
utils::println("Query: ", query);
|
||||
|
||||
"CREATE (n:LABEL {name: \"TEST2\"}) RETURN n",
|
||||
"CREATE (n:LABEL {name: \"TEST3\"}) RETURN n",
|
||||
"CREATE (n:OTHER {name: \"TEST4\"}) RETURN n"
|
||||
"CREATE (n:ACCOUNT {id: 2322, name: \"TEST\", country: \"Croatia\", "
|
||||
"created_at: 2352352}) RETURN n",
|
||||
"MATCH (n {id: 0}) RETURN n", "MATCH (n {id: 1}) RETURN n",
|
||||
"MATCH (n {id: 2}) RETURN n", "MATCH (n {id: 3}) RETURN n",
|
||||
"MATCH (a {id:0}), (p {id: 1}) CREATE (a)-[r:IS]->(p) RETURN r",
|
||||
"MATCH (a {id:1}), (p {id: 2}) CREATE (a)-[r:IS]->(p) RETURN r",
|
||||
"MATCH ()-[r]-() WHERE ID(r)=0 RETURN r",
|
||||
"MATCH ()-[r]-() WHERE ID(r)=1 RETURN r",
|
||||
"MATCH (n: {id: 0}) SET n.name = \"TEST100\" RETURN n",
|
||||
"MATCH (n: {id: 1}) SET n.name = \"TEST101\" RETURN n",
|
||||
"MATCH (n: {id: 0}) SET n.name = \"TEST102\" RETURN n",
|
||||
"MATCH (n:LABEL) RETURN n", "MATCH (n1), (n2) WHERE ID(n1)=0 AND "
|
||||
"ID(n2)=1 CREATE (n1)<-[r:IS {age: "
|
||||
"25,weight: 70}]-(n2) RETURN r",
|
||||
"MATCH (n) RETURN n", "MATCH (n:LABEL) RETURN n", "MATCH (n) DELETE n ",
|
||||
"MATCH (n:LABEL) DELETE n", "MATCH (n) WHERE ID(n) = 0 DELETE n",
|
||||
"MATCH ()-[r]-() WHERE ID(r) = 0 DELETE r", "MATCH ()-[r]-() DELETE r",
|
||||
"MATCH ()-[r:TYPE]-() DELETE r",
|
||||
"MATCH (n)-[:TYPE]->(m) WHERE ID(n) = 0 RETURN m",
|
||||
"MATCH (n)-[:TYPE]->(m) WHERE n.name = \"kruno\" RETURN m",
|
||||
"MATCH (n)-[:TYPE]->(m) WHERE n.name = \"kruno\" RETURN n,m",
|
||||
"MATCH (n:LABEL)-[:TYPE]->(m) RETURN n"
|
||||
|
||||
// CREATE and MATCH multiple labels and properties
|
||||
// "CREATE (n:LABEL1:LABEL2 {name: \"TEST01\", age: 20}) RETURN n",
|
||||
// "MATCH (n:LABEL1:LABEL2 {name: \"TEST01\", age: 20}) RETURN n"
|
||||
};
|
||||
|
||||
for (auto &query : queries) {
|
||||
auto stripped = stripper.strip(query);
|
||||
std::cout << "Query hash: " << stripped.hash << std::endl;
|
||||
utils::println("Hash: ", stripped.hash);
|
||||
|
||||
// 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("------------------------ PASS");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1,13 +1,8 @@
|
||||
#include "query/hardcode/queries.hpp"
|
||||
|
||||
#include <random>
|
||||
|
||||
#ifdef BARRIER
|
||||
#include "barrier/barrier.cpp"
|
||||
#endif
|
||||
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
#include "query/hardcode/basic.hpp"
|
||||
#include "query/strip/stripper.hpp"
|
||||
#include "storage/indexes/indexes.hpp"
|
||||
#include "utils/sysinfo/memory.hpp"
|
||||
@ -24,16 +19,13 @@ void run(size_t n, std::string &query, Db &db)
|
||||
{
|
||||
auto stripper = make_query_stripper(TK_LONG, TK_FLOAT, TK_STR, TK_BOOL);
|
||||
|
||||
#ifdef BARRIER
|
||||
auto qf = load_queries(barrier::trans(db));
|
||||
#else
|
||||
auto qf = load_queries(db);
|
||||
#endif
|
||||
auto qf = hardcode::load_basic_functions(db);
|
||||
|
||||
auto stripped = stripper.strip(query);
|
||||
std::cout << "Running query [" << stripped.hash << "] for " << n << " time."
|
||||
<< std::endl;
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
properties_t vec = stripped.arguments;
|
||||
assert(qf[stripped.hash](std::move(vec)));
|
||||
}
|
||||
@ -42,11 +34,7 @@ void run(size_t n, std::string &query, Db &db)
|
||||
void add_edge(size_t n, Db &db)
|
||||
{
|
||||
auto stripper = make_query_stripper(TK_LONG, TK_FLOAT, TK_STR, TK_BOOL);
|
||||
#ifdef BARRIER
|
||||
auto qf = load_queries(barrier::trans(db));
|
||||
#else
|
||||
auto qf = load_queries(db);
|
||||
#endif
|
||||
auto qf = hardcode::load_basic_functions(db);
|
||||
|
||||
std::string query = "MATCH (n1), (n2) WHERE ID(n1)=0 AND "
|
||||
"ID(n2)=1 CREATE (n1)<-[r:IS {age: "
|
||||
@ -57,15 +45,17 @@ void add_edge(size_t n, Db &db)
|
||||
<< " time to add edge." << std::endl;
|
||||
|
||||
std::vector<int64_t> vertices;
|
||||
for (auto &v : db.graph.vertices.access()) {
|
||||
for (auto &v : db.graph.vertices.access())
|
||||
{
|
||||
vertices.push_back(v.second.id);
|
||||
}
|
||||
|
||||
auto rand = rand_gen(vertices.size());
|
||||
for (int i = 0; i < n; i++) {
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
properties_t vec = stripped.arguments;
|
||||
vec[0] = Property(Int64(vertices[rand()]), Flags::Int64);
|
||||
vec[1] = Property(Int64(vertices[rand()]), Flags::Int64);
|
||||
vec[0] = Property(Int64(vertices[rand()]), Flags::Int64);
|
||||
vec[1] = Property(Int64(vertices[rand()]), Flags::Int64);
|
||||
assert(qf[stripped.hash](std::move(vec)));
|
||||
}
|
||||
}
|
||||
@ -99,8 +89,9 @@ size_t size(Db &db, IndexHolder<TypeGroupVertex, std::nullptr_t> &h)
|
||||
DbAccessor t(db);
|
||||
|
||||
size_t count = 0;
|
||||
auto oin = h.get_read();
|
||||
if (oin.is_present()) {
|
||||
auto oin = h.get_read();
|
||||
if (oin.is_present())
|
||||
{
|
||||
oin.get()->for_range(t).for_all([&](auto va) mutable { count++; });
|
||||
}
|
||||
|
||||
@ -132,7 +123,7 @@ void clean_edge(Db &db)
|
||||
void clear_database(Db &db)
|
||||
{
|
||||
std::string delete_all_vertices = "MATCH (n) DELETE n";
|
||||
std::string delete_all_edges = "MATCH ()-[r]-() DELETE r";
|
||||
std::string delete_all_edges = "MATCH ()-[r]-() DELETE r";
|
||||
|
||||
run(1, delete_all_edges, db);
|
||||
run(1, delete_all_vertices, db);
|
||||
@ -147,14 +138,16 @@ bool equal(Db &a, Db &b)
|
||||
auto acc_a = a.graph.vertices.access();
|
||||
auto acc_b = b.graph.vertices.access();
|
||||
|
||||
if (acc_a.size() != acc_b.size()) {
|
||||
if (acc_a.size() != acc_b.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it_a = acc_a.begin();
|
||||
auto it_b = acc_b.begin();
|
||||
|
||||
for (auto i = acc_a.size(); i > 0; i--) {
|
||||
for (auto i = acc_a.size(); i > 0; i--)
|
||||
{
|
||||
// TODO: compare
|
||||
}
|
||||
}
|
||||
@ -163,14 +156,16 @@ bool equal(Db &a, Db &b)
|
||||
auto acc_a = a.graph.edges.access();
|
||||
auto acc_b = b.graph.edges.access();
|
||||
|
||||
if (acc_a.size() != acc_b.size()) {
|
||||
if (acc_a.size() != acc_b.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it_a = acc_a.begin();
|
||||
auto it_b = acc_b.begin();
|
||||
|
||||
for (auto i = acc_a.size(); i > 0; i--) {
|
||||
for (auto i = acc_a.size(); i > 0; i--)
|
||||
{
|
||||
// TODO: compare
|
||||
}
|
||||
}
|
||||
@ -190,7 +185,7 @@ int main(void)
|
||||
std::string create_vertex_other =
|
||||
"CREATE (n:OTHER {name: \"cleaner_test\"}) RETURN n";
|
||||
std::string delete_label_vertices = "MATCH (n:LABEL) DELETE n";
|
||||
std::string delete_all_vertices = "MATCH (n) DELETE n";
|
||||
std::string delete_all_vertices = "MATCH (n) DELETE n";
|
||||
|
||||
// ******************************* TEST 1 ********************************//
|
||||
{
|
||||
|
@ -19,14 +19,18 @@ int main(int argc, char *argv[])
|
||||
auto arguments = all_arguments(argc, argv);
|
||||
|
||||
// // query extraction
|
||||
auto cypher_query = extract_query(arguments);
|
||||
cout << "QUERY: " << cypher_query << endl;
|
||||
auto queries = extract_queries(arguments);
|
||||
|
||||
auto print_visitor = new PrintVisitor(cout);
|
||||
cypher::Compiler compiler;
|
||||
auto tree = compiler.syntax_tree(cypher_query);
|
||||
tree.root->accept(*print_visitor);
|
||||
cout << endl;
|
||||
|
||||
for (auto &query : queries)
|
||||
{
|
||||
cout << "QUERY: " << query << endl;
|
||||
auto print_visitor = new PrintVisitor(cout);
|
||||
cypher::Compiler compiler;
|
||||
auto tree = compiler.syntax_tree(query);
|
||||
tree.root->accept(*print_visitor);
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,15 +1,11 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "query/hardcode/queries.hpp"
|
||||
|
||||
#ifdef BARRIER
|
||||
#include "barrier/barrier.cpp"
|
||||
#endif
|
||||
|
||||
#include "communication/bolt/v1/serialization/bolt_serializer.hpp"
|
||||
#include "database/db.hpp"
|
||||
#include "logging/default.hpp"
|
||||
#include "logging/streams/stdout.hpp"
|
||||
#include "query/hardcode/basic.hpp"
|
||||
#include "query/hardcode/dressipi.hpp"
|
||||
#include "query/strip/stripper.hpp"
|
||||
#include "storage/edges.cpp"
|
||||
#include "storage/edges.hpp"
|
||||
@ -24,25 +20,23 @@ int main(int argc, char **argv)
|
||||
logging::log->pipe(std::make_unique<Stdout>());
|
||||
|
||||
Db db;
|
||||
#ifdef BARRIER
|
||||
auto queries = load_queries(barrier::trans(db));
|
||||
#else
|
||||
auto queries = load_queries(db);
|
||||
#endif
|
||||
auto queries = hardcode::load_basic_functions(db);
|
||||
|
||||
auto stripper = make_query_stripper(TK_LONG, TK_FLOAT, TK_STR, TK_BOOL);
|
||||
|
||||
vector<string> history;
|
||||
string command;
|
||||
cout << "-- Memgraph query engine --" << endl;
|
||||
do {
|
||||
do
|
||||
{
|
||||
|
||||
cout << "> ";
|
||||
getline(cin, command);
|
||||
history.push_back(command);
|
||||
auto stripped = stripper.strip(command);
|
||||
|
||||
if (queries.find(stripped.hash) == queries.end()) {
|
||||
if (queries.find(stripped.hash) == queries.end())
|
||||
{
|
||||
cout << "unsupported query" << endl;
|
||||
continue;
|
||||
}
|
||||
|
@ -15,18 +15,24 @@ int main(int argc, char **argv)
|
||||
auto arguments = all_arguments(argc, argv);
|
||||
|
||||
// query extraction
|
||||
auto input_query = extract_query(arguments);
|
||||
auto queries = extract_queries(arguments);
|
||||
|
||||
QueryPreprocessor preprocessor;
|
||||
auto preprocessed = preprocessor.preprocess(input_query);
|
||||
|
||||
cout << "QUERY: " << input_query << endl;
|
||||
cout << "STRIPPED QUERY: " << preprocessed.query << endl;
|
||||
cout << "QUERY HASH: " << preprocessed.hash << endl;
|
||||
cout << "PROPERTIES:" << endl;
|
||||
for (auto property : preprocessed.arguments) {
|
||||
cout << " " << property << endl;
|
||||
for (auto &query : queries)
|
||||
{
|
||||
auto preprocessed = preprocessor.preprocess(query);
|
||||
cout << "QUERY: " << query << endl;
|
||||
cout << "STRIPPED QUERY: " << preprocessed.query << endl;
|
||||
cout << "QUERY HASH: " << preprocessed.hash << endl;
|
||||
cout << "PROPERTIES:" << endl;
|
||||
for (auto property : preprocessed.arguments) {
|
||||
cout << " " << property << endl;
|
||||
}
|
||||
cout << "-----------------------------" << endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user