diff --git a/cmake/copy_includes.cmake b/cmake/copy_includes.cmake index bdf2b667c..7835717de 100644 --- a/cmake/copy_includes.cmake +++ b/cmake/copy_includes.cmake @@ -29,6 +29,7 @@ FILE(COPY ${include_dir}/storage/model/properties/stored_property.hpp DESTINATIO FILE(COPY ${include_dir}/storage/model/properties/property_holder.hpp DESTINATION ${build_include_dir}/storage/model/properties) FILE(COPY ${include_dir}/storage/type_group_edge.hpp DESTINATION ${build_include_dir}/storage) FILE(COPY ${include_dir}/storage/type_group_vertex.hpp DESTINATION ${build_include_dir}/storage) +FILE(COPY ${include_dir}/storage/edge_x_vertex.hpp DESTINATION ${build_include_dir}/storage) FILE(COPY ${include_dir}/query/util.hpp DESTINATION ${build_include_dir}/query) FILE(COPY ${include_dir}/query/i_plan_cpu.hpp DESTINATION ${build_include_dir}/query) diff --git a/include/query/engine.hpp b/include/query/engine.hpp index a468244dd..1e6dabb88 100644 --- a/include/query/engine.hpp +++ b/include/query/engine.hpp @@ -33,10 +33,11 @@ public: "Unable to execute query (executor returned false)"); } return result; + } catch (CypherLexicalError &e) { + logger.error("CypherLexicalError: {}", std::string(e.what())); + throw e; } catch (QueryEngineException &e) { - // in this case something fatal went wrong logger.error("QueryEngineException: {}", std::string(e.what())); - // return false; throw e; } catch (std::exception &e) { throw e; diff --git a/include/query/util.hpp b/include/query/util.hpp index 2452be573..5fc05ab41 100644 --- a/include/query/util.hpp +++ b/include/query/util.hpp @@ -46,7 +46,7 @@ std::string code_line(const std::string &format_str, const Args &... args) } using name_properties_t = std::vector>; -using indices_t = std::map; +using indices_t = std::map; auto query_properties(indices_t &indices, properties_t &values) { diff --git a/release/alpha.sh b/release/alpha.sh index 1459f91df..928c39ffe 100755 --- a/release/alpha.sh +++ b/release/alpha.sh @@ -37,7 +37,10 @@ cp -r include ../release/${exe_name}/include cp -r template ../release/${exe_name}/template cp -r ../config ../release/${exe_name}/config -mkdir -p ../release/${exe_name}/compiled/cpu +# create compiled folder and copy hard coded queries +mkdir -p ../release/${exe_name}/compiled/cpu/hardcode +cp ../tests/integration/hardcoded_query/*.cpp ../release/${exe_name}/compiled/cpu/hardcode +cp ../tests/integration/hardcoded_query/*.hpp ../release/${exe_name}/compiled/cpu/hardcode echo "Memgraph Release Building DONE" diff --git a/src/communication/bolt/v1/states/executor.cpp b/src/communication/bolt/v1/states/executor.cpp index 4d3371235..6c88e0be2 100644 --- a/src/communication/bolt/v1/states/executor.cpp +++ b/src/communication/bolt/v1/states/executor.cpp @@ -31,13 +31,27 @@ State *Executor::run(Session &session) return this->run(session, q); // TODO: RETURN success MAYBE } - catch (QueryEngineException &e) + catch (const CypherLexicalError &e) + { + session.output_stream.write_failure( + {{"code", "Memgraph.CypherLexicalError"}, + {"message", e.what()}}); + session.output_stream.send(); + return session.bolt.states.error.get(); + } + catch (const QueryEngineException &e) { session.output_stream.write_failure( {{"code", "Memgraph.QueryEngineException"}, {"message", e.what()}}); session.output_stream.send(); return session.bolt.states.error.get(); + } catch (std::exception &e) { + session.output_stream.write_failure( + {{"code", "Memgraph.Exception"}, + {"message", e.what()}}); + session.output_stream.send(); + return session.bolt.states.error.get(); } } else if (message_type == MessageCode::PullAll) diff --git a/tests/integration/_hardcoded_query/dressipi.hpp b/tests/integration/_hardcoded_query/dressipi.hpp index 582c5eb23..3f7d1d6b3 100644 --- a/tests/integration/_hardcoded_query/dressipi.hpp +++ b/tests/integration/_hardcoded_query/dressipi.hpp @@ -160,6 +160,12 @@ auto load_dressipi_functions(Db &db) ea.set(score_key, std::move(args[3])); }); + // stream.write_field("r.score"); + // write_record(); + // write_list_header(1); + // write(Float(args[3])); + // chunk(); + print_entities(t); return t.commit(); @@ -261,6 +267,8 @@ auto load_dressipi_functions(Db &db) auto score_key = t.edge_property_key("score", args[3].key.flags()); + // stream.write_field("s"); + // TODO: implement bool exists = false; Option e1; @@ -277,6 +285,7 @@ auto load_dressipi_functions(Db &db) exists = true; auto ea = e1.get().update(); ea.set(score_key, args[3]); + // stream.write_edge_record(ea); }); Option e2; @@ -293,6 +302,7 @@ auto load_dressipi_functions(Db &db) exists = true; auto ea = e2.get().update(); ea.set(score_key, args[3]); + // stream.write_edge_record(ea); }); if (!exists) { @@ -306,15 +316,11 @@ auto load_dressipi_functions(Db &db) auto ea = t.edge_insert(va1, va2); ea.edge_type(score); ea.set(score_key, args[3]); + // stream.write_edge_record(ea); }); }); } - // stream.write_field("r.score"); - // write_record(); - // write_list_header(1); - // write(Float(args[3])); - // chunk(); // stream.write_field("w"); print_entities(t); diff --git a/tests/integration/hardcoded_query/11123780635391515946.cpp b/tests/integration/hardcoded_query/11123780635391515946.cpp new file mode 100644 index 000000000..55ecf8c53 --- /dev/null +++ b/tests/integration/hardcoded_query/11123780635391515946.cpp @@ -0,0 +1,65 @@ +#include +#include + +#include "query/util.hpp" +#include "query/i_plan_cpu.hpp" +#include "storage/model/properties/all.hpp" +#include "using.hpp" + +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 +{ +public: + + bool run(Db &db, plan_args_t &args, Stream &stream) override + { + DbAccessor t(db); + + indices_t indices = {{"garment_id", 0}}; + auto properties = query_properties(indices, args); + + auto &label = t.label_find_or_create("garment"); + + stream.write_field("labels(g)"); + + label.index() + .for_range(t) + .properties_filter(t, properties) + .for_all([&](auto va) -> void { + va.stream_repr(std::cout); + auto &ff_label = t.label_find_or_create("FF"); + va.add_label(ff_label); + auto &labels = va.labels(); + + stream.write_record(); + stream.write_list_header(1); + stream.write_list_header(labels.size()); + for (auto &label : labels) + { + stream.write(label.get().str()); + } + stream.chunk(); + }); + + stream.write_meta(\"rw"); + + return t.commit(); + } + + ~CodeCPU() {} +}; + +extern "C" IPlanCPU* produce() +{ + return new CodeCPU(); +} + +extern "C" void destruct(IPlanCPU* p) +{ + delete p; +} diff --git a/tests/integration/hardcoded_query/11538263096707897794.cpp b/tests/integration/hardcoded_query/11538263096707897794.cpp new file mode 100644 index 000000000..d0c6b7f6a --- /dev/null +++ b/tests/integration/hardcoded_query/11538263096707897794.cpp @@ -0,0 +1,51 @@ +#include +#include + +#include "query/util.hpp" +#include "query/i_plan_cpu.hpp" +#include "storage/model/properties/all.hpp" +#include "using.hpp" + +using std::cout; +using std::endl; + +// Query: MATCH (p:garment {garment_id: 1}) DELETE g +// Hash: 11538263096707897794 + +class CodeCPU : public IPlanCPU +{ +public: + + bool run(Db &db, plan_args_t &args, Stream &stream) override + { + DbAccessor t(db); + + indices_t indices = {{"garment_id", 0}}; + auto properties = query_properties(indices, args); + + auto &label = t.label_find_or_create("garment"); + + label.index() + .for_range(t) + .properties_filter(t, properties) + .for_all([&](auto va) { va.remove(); }); + + stream.write_empty_fields(); + stream.write_meta("w"); + + return t.commit(); + + } + + ~CodeCPU() {} +}; + +extern "C" IPlanCPU* produce() +{ + return new CodeCPU(); +} + +extern "C" void destruct(IPlanCPU* p) +{ + delete p; +} diff --git a/tests/integration/hardcoded_query/17158428452166262783.cpp b/tests/integration/hardcoded_query/17158428452166262783.cpp new file mode 100644 index 000000000..78f9c4b13 --- /dev/null +++ b/tests/integration/hardcoded_query/17158428452166262783.cpp @@ -0,0 +1,54 @@ +#include +#include + +#include "query/util.hpp" +#include "query/i_plan_cpu.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 + +class CodeCPU : public IPlanCPU +{ +public: + + bool run(Db &db, plan_args_t &args, Stream &stream) override + { + DbAccessor t(db); + + auto profile_id = + t.vertex_property_key("profile_id", args[0].key.flags()); + auto partner_id = + t.vertex_property_key("partner_id", args[1].key.flags()); + + auto va = t.vertex_insert(); + va.set(profile_id, std::move(args[0])); + va.set(partner_id, std::move(args[1])); + + auto &profile = t.label_find_or_create("profile"); + va.add_label(profile); + + stream.write_field("p"); + stream.write_vertex_record(va); + stream.write_meta("w"); + + return t.commit(); + + } + + ~CodeCPU() {} +}; + +extern "C" IPlanCPU* produce() +{ + return new CodeCPU(); +} + +extern "C" void destruct(IPlanCPU* p) +{ + delete p; +} diff --git a/tests/integration/hardcoded_query/17506488413143988006.cpp b/tests/integration/hardcoded_query/17506488413143988006.cpp new file mode 100644 index 000000000..d8d8bd05b --- /dev/null +++ b/tests/integration/hardcoded_query/17506488413143988006.cpp @@ -0,0 +1,53 @@ +#include +#include + +#include "query/util.hpp" +#include "query/i_plan_cpu.hpp" +#include "storage/model/properties/all.hpp" +#include "using.hpp" + +using std::cout; +using std::endl; + +// Query: MATCH (p:profile {partner_id: 1}) RETURN p +// Hash: 17506488413143988006 + +class CodeCPU : public IPlanCPU +{ +public: + + bool run(Db &db, plan_args_t &args, Stream &stream) override + { + DbAccessor t(db); + + indices_t indices = {{"partner_id", 0}}; + auto properties = query_properties(indices, args); + + auto &label = t.label_find_or_create("profile"); + + stream.write_field("p"); + + label.index() + .for_range(t) + .properties_filter(t, properties) + .for_all([&](auto va) { + stream.write_vertex_record(va); + }); + + stream.write_meta("r"); + + return t.commit(); + } + + ~CodeCPU() {} +}; + +extern "C" IPlanCPU* produce() +{ + return new CodeCPU(); +} + +extern "C" void destruct(IPlanCPU* p) +{ + delete p; +} diff --git a/tests/integration/hardcoded_query/18071907865596388702.cpp b/tests/integration/hardcoded_query/18071907865596388702.cpp index 89310b8f4..6636d1421 100644 --- a/tests/integration/hardcoded_query/18071907865596388702.cpp +++ b/tests/integration/hardcoded_query/18071907865596388702.cpp @@ -9,7 +9,8 @@ using std::cout; using std::endl; -// query: CREATE (g:garment {garment_id: 1234, garment_category_id: 1}) RETURN g +// Query: CREATE (g:garment {garment_id: 1234, garment_category_id: 1}) RETURN g +// Hash: 18071907865596388702 class CodeCPU : public IPlanCPU { diff --git a/tests/integration/hardcoded_query/2839969099736071844.cpp b/tests/integration/hardcoded_query/2839969099736071844.cpp new file mode 100644 index 000000000..590bb725b --- /dev/null +++ b/tests/integration/hardcoded_query/2839969099736071844.cpp @@ -0,0 +1,58 @@ +#include +#include + +#include "query/util.hpp" +#include "query/i_plan_cpu.hpp" +#include "storage/model/properties/all.hpp" +#include "using.hpp" + +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 +{ +public: + + bool run(Db &db, plan_args_t &args, Stream &stream) override + { + DbAccessor t(db); + + auto reveals_key = + t.vertex_property_key("reveals", args[1].key.flags()); + + indices_t indices = {{"garment_id", 0}}; + auto properties = query_properties(indices, args); + + auto &label = t.label_find_or_create("garment"); + + stream.write_field("g"); + + label.index() + .for_range(t) + .properties_filter(t, properties) + .fill() + .for_all([&](auto va) { + va.set(reveals_key, args[1]); + stream.write_vertex_record(va); + }); + + stream.write_meta("w"); + + return t.commit(); + } + + ~CodeCPU() {} +}; + +extern "C" IPlanCPU* produce() +{ + return new CodeCPU(); +} + +extern "C" void destruct(IPlanCPU* p) +{ + delete p; +} diff --git a/tests/integration/hardcoded_query/3782642357973971504.cpp b/tests/integration/hardcoded_query/3782642357973971504.cpp new file mode 100644 index 000000000..12543d516 --- /dev/null +++ b/tests/integration/hardcoded_query/3782642357973971504.cpp @@ -0,0 +1,74 @@ +#include +#include + +#include "query/util.hpp" +#include "query/i_plan_cpu.hpp" +#include "storage/model/properties/all.hpp" +#include "using.hpp" + +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 +{ +public: + + bool run(Db &db, plan_args_t &args, Stream &stream) override + { + DbAccessor t(db); + + // TODO: support for index on label and property + + // prepare iterator for g1 + indices_t indices_1 = {{"garment_id", 0}}; + auto properties_1 = query_properties(indices_1, args); + auto &label_1 = t.label_find_or_create("garment"); + + auto it_vertex_1 = + label_1.index().for_range(t).properties_filter(t, properties_1); + + // prepare iterator for g1 + indices_t indices_2 = {{"garment_id", 1}}; + auto properties_2 = query_properties(indices_2, args); + auto &label_2 = t.label_find_or_create("garment"); + + auto it_vertex_2 = + label_2.index().for_range(t).properties_filter(t, properties_2); + + auto &edge_type = t.type_find_or_create("default_outfit"); + + // TODO: create g1 and g2 if don't exist + + // TODO: figure out something better + + stream.write_field("r"); + + it_vertex_1.fill().for_all([&](auto va1) -> void { + it_vertex_2.fill().for_all([&](auto va2) -> void { + auto edge_accessor = t.edge_insert(va1, va2); + edge_accessor.edge_type(edge_type); + + stream.write_edge_record(edge_accessor); + }); + }); + + stream.write_meta("w"); + + return t.commit(); + } + + ~CodeCPU() {} +}; + +extern "C" IPlanCPU* produce() +{ + return new CodeCPU(); +} + +extern "C" void destruct(IPlanCPU* p) +{ + delete p; +} diff --git a/tests/integration/hardcoded_query/4798158026600988079.cpp b/tests/integration/hardcoded_query/4798158026600988079.cpp new file mode 100644 index 000000000..9195c53cc --- /dev/null +++ b/tests/integration/hardcoded_query/4798158026600988079.cpp @@ -0,0 +1,44 @@ +#include +#include + +#include "query/util.hpp" +#include "query/i_plan_cpu.hpp" +#include "storage/model/properties/all.hpp" +#include "using.hpp" + +using std::cout; +using std::endl; + +// Query: MATCH (n) DETACH DELETE n +// Hash: 4798158026600988079 + +class CodeCPU : public IPlanCPU +{ +public: + + bool run(Db &db, plan_args_t &args, Stream &stream) override + { + DbAccessor t(db); + + t.edge_access().fill().for_all([&](auto e) { e.remove(); }); + t.vertex_access().fill().isolated().for_all( + [&](auto a) { a.remove(); }); + + stream.write_empty_fields(); + stream.write_meta("w"); + + return t.commit(); + } + + ~CodeCPU() {} +}; + +extern "C" IPlanCPU* produce() +{ + return new CodeCPU(); +} + +extern "C" void destruct(IPlanCPU* p) +{ + delete p; +} diff --git a/tests/integration/hardcoded_query/674581607834128909.cpp b/tests/integration/hardcoded_query/674581607834128909.cpp new file mode 100644 index 000000000..34cd7df4b --- /dev/null +++ b/tests/integration/hardcoded_query/674581607834128909.cpp @@ -0,0 +1,89 @@ +#include +#include + +#include "query/util.hpp" +#include "query/i_plan_cpu.hpp" +#include "storage/model/properties/all.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 +{ +public: + + bool run(Db &db, plan_args_t &args, Stream &stream) override + { + DbAccessor t(db); + + auto &profile = t.label_find_or_create("profile"); + auto &score = t.type_find_or_create("score"); + auto &garment = t.label_find_or_create("garment"); + + indices_t profile_ind = {{"profile_id", 0}, {"partner_id", 1}}; + indices_t garment_ind = {{"garment_id", 2}}; + + auto profile_prop = query_properties(profile_ind, args); + auto garment_prop = query_properties(garment_ind, args); + + auto score_key = t.edge_property_key("score", args[3].key.flags()); + + // TODO: decide path (which index is better) + // 3 options p->s->g, g->s->p, g<-s->p + // NOTE! both direections have to be chacked + // because pattern is non directional + // OR + // even better, use index on label and property + + // just one option p->s->g! + Option e1; + profile.index() + .for_range(t) + .properties_filter(t, profile_prop) + .out() + .type(score) + .clone_to(e1) + .to() + .label(garment) + .properties_filter(t, garment_prop) + .for_all([&](auto va) -> void { + auto ea = e1.get().update(); + ea.set(score_key, std::move(args[3])); + }); + + Option e2; + profile.index() + .for_range(t) + .properties_filter(t, profile_prop) + .in() + .type(score) + .clone_to(e1) + .from() + .label(garment) + .properties_filter(t, garment_prop) + .for_all([&](auto va) -> void { + auto ea = e2.get().update(); + ea.set(score_key, std::move(args[3])); + }); + + + return t.commit(); + + } + + ~CodeCPU() {} +}; + +extern "C" IPlanCPU* produce() +{ + return new CodeCPU(); +} + +extern "C" void destruct(IPlanCPU* p) +{ + delete p; +} diff --git a/tests/integration/hardcoded_query/6763665709953344106.cpp b/tests/integration/hardcoded_query/6763665709953344106.cpp new file mode 100644 index 000000000..ab8d2924f --- /dev/null +++ b/tests/integration/hardcoded_query/6763665709953344106.cpp @@ -0,0 +1,51 @@ +#include +#include + +#include "query/util.hpp" +#include "query/i_plan_cpu.hpp" +#include "storage/model/properties/all.hpp" +#include "using.hpp" + +using std::cout; +using std::endl; + +// Query: MATCH (p:profile {profile_id: 1}) DELETE p +// Hash: 6763665709953344106 + +class CodeCPU : public IPlanCPU +{ +public: + + bool run(Db &db, plan_args_t &args, Stream &stream) override + { + DbAccessor t(db); + + indices_t indices = {{"profile_id", 0}}; + auto properties = query_properties(indices, args); + + auto &label = t.label_find_or_create("profile"); + + label.index() + .for_range(t) + .properties_filter(t, properties) + .for_all([&](auto va) { va.remove(); }); + + stream.write_empty_fields(); + stream.write_meta("w"); + + return t.commit(); + + } + + ~CodeCPU() {} +}; + +extern "C" IPlanCPU* produce() +{ + return new CodeCPU(); +} + +extern "C" void destruct(IPlanCPU* p) +{ + delete p; +} diff --git a/tests/integration/hardcoded_query/7756609649964321221.cpp b/tests/integration/hardcoded_query/7756609649964321221.cpp new file mode 100644 index 000000000..58d6691d7 --- /dev/null +++ b/tests/integration/hardcoded_query/7756609649964321221.cpp @@ -0,0 +1,53 @@ +#include +#include + +#include "query/util.hpp" +#include "query/i_plan_cpu.hpp" +#include "storage/model/properties/all.hpp" +#include "using.hpp" + +using std::cout; +using std::endl; + +// Query: MATCH (g:garment {garment_id: 1}) RETURN g +// Hash: 7756609649964321221 + +class CodeCPU : public IPlanCPU +{ +public: + + bool run(Db &db, plan_args_t &args, Stream &stream) override + { + DbAccessor t(db); + + indices_t indices = {{"garment_id", 0}}; + auto properties = query_properties(indices, args); + + auto &label = t.label_find_or_create("garment"); + + stream.write_field("g"); + + label.index() + .for_range(t) + .properties_filter(t, properties) + .for_all([&](auto va) -> void { + stream.write_vertex_record(va); + }); + + stream.write_meta("w"); + + return t.commit(); + } + + ~CodeCPU() {} +}; + +extern "C" IPlanCPU* produce() +{ + return new CodeCPU(); +} + +extern "C" void destruct(IPlanCPU* p) +{ + delete p; +} diff --git a/tests/integration/hardcoded_query/7871009397157280694.cpp b/tests/integration/hardcoded_query/7871009397157280694.cpp new file mode 100644 index 000000000..91e0a0aa9 --- /dev/null +++ b/tests/integration/hardcoded_query/7871009397157280694.cpp @@ -0,0 +1,106 @@ +#include +#include + +#include "query/util.hpp" +#include "query/i_plan_cpu.hpp" +#include "storage/model/properties/all.hpp" +#include "storage/edge_x_vertex.hpp" +#include "using.hpp" + +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 +{ +public: + + bool run(Db &db, plan_args_t &args, Stream &stream) override + { + DbAccessor t(db); + + auto &profile = t.label_find_or_create("profile"); + auto &score = t.type_find_or_create("score"); + auto &garment = t.label_find_or_create("garment"); + + indices_t profile_ind = {{"profile_id", 0}, {"partner_id", 1}}; + indices_t garment_ind = {{"garment_id", 2}}; + + auto profile_prop = query_properties(profile_ind, args); + auto garment_prop = query_properties(garment_ind, args); + + auto score_key = t.edge_property_key("score", args[3].key.flags()); + + stream.write_field("s"); + + // TODO: implement + bool exists = false; + Option e1; + profile.index() + .for_range(t) + .properties_filter(t, profile_prop) + .out() + .type(score) + .clone_to(e1) + .to() + .label(garment) + .properties_filter(t, garment_prop) + .for_all([&](auto va) -> void { + exists = true; + auto ea = e1.get().update(); + ea.set(score_key, args[3]); + stream.write_edge_record(ea); + }); + + Option e2; + profile.index() + .for_range(t) + .properties_filter(t, profile_prop) + .in() + .type(score) + .clone_to(e1) + .from() + .label(garment) + .properties_filter(t, garment_prop) + .for_all([&](auto va) -> void { + exists = true; + auto ea = e2.get().update(); + ea.set(score_key, args[3]); + stream.write_edge_record(ea); + }); + + if (!exists) { + auto it_vertex_garment = + garment.index().for_range(t).properties_filter(t, garment_prop); + auto it_vertex_profile = + profile.index().for_range(t).properties_filter(t, profile_prop); + + it_vertex_profile.fill().for_all([&](auto va1) -> void { + it_vertex_garment.fill().for_all([&](auto va2) -> void { + auto ea = t.edge_insert(va1, va2); + ea.edge_type(score); + ea.set(score_key, args[3]); + stream.write_edge_record(ea); + }); + }); + } + + stream.write_field("w"); + + return t.commit(); + } + + ~CodeCPU() {} +}; + +extern "C" IPlanCPU* produce() +{ + return new CodeCPU(); +} + +extern "C" void destruct(IPlanCPU* p) +{ + delete p; +} diff --git a/tests/integration/hardcoded_query/9459600951073026137.cpp b/tests/integration/hardcoded_query/9459600951073026137.cpp new file mode 100644 index 000000000..e1a432bb6 --- /dev/null +++ b/tests/integration/hardcoded_query/9459600951073026137.cpp @@ -0,0 +1,91 @@ +#include +#include + +#include "query/util.hpp" +#include "query/i_plan_cpu.hpp" +#include "storage/model/properties/all.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 + +class CodeCPU : public IPlanCPU +{ +public: + + bool run(Db &db, plan_args_t &args, Stream &stream) override + { + DbAccessor t(db); + + auto &profile = t.label_find_or_create("profile"); + auto &score = t.type_find_or_create("score"); + auto &garment = t.label_find_or_create("garment"); + + indices_t profile_ind = {{"profile_id", 0}, {"partner_id", 1}}; + indices_t garment_ind = {{"garment_id", 2}}; + + auto profile_prop = query_properties(profile_ind, args); + auto garment_prop = query_properties(garment_ind, args); + + auto score_key = t.edge_property_key("score", args[3].key.flags()); + + // TODO: decide path (which index is better) + // 3 options p->s->g, g->s->p, g<-s->p + // NOTE! both direections have to be chacked + // because pattern is non directional + // OR + // even better, use index on label and property + + // just one option p->s->g! + Option e1; + profile.index() + .for_range(t) + .properties_filter(t, profile_prop) + .out() + .type(score) + .clone_to(e1) + .to() + .label(garment) + .properties_filter(t, garment_prop) + .for_all([&](auto va) -> void { + auto ea = e1.get().update(); + ea.remove(); + }); + + Option e2; + profile.index() + .for_range(t) + .properties_filter(t, profile_prop) + .in() + .type(score) + .clone_to(e1) + .from() + .label(garment) + .properties_filter(t, garment_prop) + .for_all([&](auto va) -> void { + auto ea = e2.get().update(); + ea.remove(); + }); + + stream.write_empty_fields(); + stream.write_meta("w"); + + return t.commit(); + + } + + ~CodeCPU() {} +}; + +extern "C" IPlanCPU* produce() +{ + return new CodeCPU(); +} + +extern "C" void destruct(IPlanCPU* p) +{ + delete p; +} diff --git a/tests/integration/hardcoded_query/template b/tests/integration/hardcoded_query/template index f5cd0bd6a..6d73f6477 100644 --- a/tests/integration/hardcoded_query/template +++ b/tests/integration/hardcoded_query/template @@ -4,30 +4,31 @@ #include "query/util.hpp" #include "query/i_plan_cpu.hpp" #include "storage/model/properties/all.hpp" +#include "using.hpp" using std::cout; using std::endl; // query: -class CodeCPU : public IPlanCPU<{{stream}}> +class CodeCPU : public IPlanCPU { public: - bool run(Db &db, plan_args_t &args, {{stream}} &stream) override + bool run(Db &db, plan_args_t &args, Stream &stream) override { -{{code}} + } - ~{{class_name}}() {} + ~CodeCPU() {} }; -extern "C" IPlanCPU<{{stream}}>* produce() +extern "C" IPlanCPU* produce() { - return new {{class_name}}(); + return new CodeCPU(); } -extern "C" void destruct(IPlanCPU<{{stream}}>* p) +extern "C" void destruct(IPlanCPU* p) { delete p; }