diff --git a/flex/engines/graph_db/runtime/codegen/builders/builders.h b/flex/engines/graph_db/runtime/codegen/builders/builders.h index 5f7beefeeb9e..4da1c11276ce 100644 --- a/flex/engines/graph_db/runtime/codegen/builders/builders.h +++ b/flex/engines/graph_db/runtime/codegen/builders/builders.h @@ -20,6 +20,7 @@ limitations under the License. #include "flex/engines/graph_db/runtime/codegen/building_context.h" #include "flex/engines/graph_db/runtime/codegen/exprs/expr_builder.h" +#include "flex/engines/graph_db/runtime/codegen/utils/utils.h" #include "flex/engines/graph_db/runtime/common/utils.h" #include "flex/proto_generated_gie/algebra.pb.h" #include "flex/proto_generated_gie/common.pb.h" @@ -37,6 +38,12 @@ std::string build_limit(BuildingContext& context, const algebra::Limit& opr); std::string build_get_v(BuildingContext& context, const physical::GetV& opr); +std::string build_edge_expand(BuildingContext& context, + const physical::EdgeExpand& opr, + const physical::PhysicalOpr_MetaData& meta); + +std::string build_select(BuildingContext& context, const algebra::Select& opr); + } // namespace runtime } // namespace gs #endif // RUNTIME_CODEGEN_BUILDERS_BUILDERS_H_ \ No newline at end of file diff --git a/flex/engines/graph_db/runtime/codegen/builders/edge_expand_builder.cc b/flex/engines/graph_db/runtime/codegen/builders/edge_expand_builder.cc new file mode 100644 index 000000000000..7dde14698ec3 --- /dev/null +++ b/flex/engines/graph_db/runtime/codegen/builders/edge_expand_builder.cc @@ -0,0 +1,90 @@ +#include "flex/engines/graph_db/runtime/codegen/builders/builders.h" + +namespace gs { +namespace runtime { +class EdgeExpandBuilder { + public: + EdgeExpandBuilder(BuildingContext& context) : context_(context) {}; + + std::string Build(const physical::EdgeExpand& opr, + const physical::PhysicalOpr_MetaData& meta) { + int tag = -1; + if (opr.has_v_tag()) { + tag = opr.v_tag().value(); + } + Direction dir = parse_direction(opr.direction()); + CHECK(!opr.is_optional()); + + CHECK(opr.has_params()); + const auto& params = opr.params(); + int alias = -1; + if (opr.has_alias()) { + alias = opr.alias().value(); + } + + if (opr.expand_opt() == + physical::EdgeExpand_ExpandOpt::EdgeExpand_ExpandOpt_VERTEX) { + context_.set_alias(alias, ContextColumnType::kVertex, RTAnyType::kVertex); + if (params.has_predicate()) { + LOG(FATAL) << "not support" << params.DebugString(); + } else { + EdgeExpandParams eep; + eep.v_tag = tag; + eep.labels = parse_label_triplets(meta); + eep.dir = dir; + eep.alias = alias; + auto [cur_ctx, nxt_ctx] = context_.GetCurAndNextCtxName(); + std::string ss; + ss += "auto "; + ss += nxt_ctx + + " = EdgeExpand::expand_vertex_without_predicate(txn, std::move(" + + cur_ctx + "), " + eep.to_string() + ");\n"; + return ss; + } + } else if (opr.expand_opt() == + physical::EdgeExpand_ExpandOpt::EdgeExpand_ExpandOpt_EDGE) { + EdgeExpandParams eep; + eep.v_tag = tag; + eep.labels = parse_label_triplets(meta); + eep.dir = dir; + eep.alias = alias; + context_.set_alias(alias, ContextColumnType::kEdge, RTAnyType::kEdge); + if (params.has_predicate()) { + std::string ss; + auto [expr_name, expr_str] = + build_expr(context_, params.predicate(), VarType::kEdgeVar); + auto [cur_ctx, nxt_ctx] = context_.GetCurAndNextCtxName(); + ss += expr_str; + ss += "auto "; + ss += nxt_ctx + " = EdgeExpand::expand_edge(txn, std::move(" + cur_ctx + + "), " + eep.to_string() + ", EdgePredicate("; + ss += expr_name; + ss += "));\n"; + return ss; + } else { + auto [cur_ctx, nxt_ctx] = context_.GetCurAndNextCtxName(); + std::string ss; + ss += "auto "; + ss += nxt_ctx + + " = EdgeExpand::expand_edge_without_predicate(txn, std::move(" + + cur_ctx + "), " + eep.to_string() + ");\n"; + return ss; + } + } + + LOG(FATAL) << "not support" << opr.DebugString(); + + return ""; + } + + BuildingContext& context_; +}; + +std::string build_edge_expand(BuildingContext& context, + const physical::EdgeExpand& opr, + const physical::PhysicalOpr_MetaData& meta) { + EdgeExpandBuilder builder(context); + return builder.Build(opr, meta); +} +} // namespace runtime +} // namespace gs \ No newline at end of file diff --git a/flex/engines/graph_db/runtime/codegen/builders/get_v_builder.cc b/flex/engines/graph_db/runtime/codegen/builders/get_v_builder.cc index 74ba27b78205..a07af92a7fe4 100644 --- a/flex/engines/graph_db/runtime/codegen/builders/get_v_builder.cc +++ b/flex/engines/graph_db/runtime/codegen/builders/get_v_builder.cc @@ -32,14 +32,14 @@ class GetVBuilder { auto [cur_ctx, nxt_ctx] = context_.GetCurAndNextCtxName(); ss += "auto "; ss += (cur_ctx + " = GetV::get_vertex_from_vertices(txn, std::move(" + - cur_ctx + "), " + get_v_params.toString() + ", " + expr_name + - ");\n"); + cur_ctx + "), " + get_v_params.to_string() + + ", VertexPredicate(" + expr_name + "));\n"); return ss; } else if (opt == VOpt::kEnd || opt == VOpt::kStart) { auto [cur_ctx, nxt_ctx] = context_.GetCurAndNextCtxName(); ss += "auto "; ss += (nxt_ctx + " = GetV::get_vertex_from_edges(txn, std::move(" + - cur_ctx + "), " + get_v_params.toString() + ", " + expr_name + + cur_ctx + "), " + get_v_params.to_string() + ", " + expr_name + ");\n"); return ss; } @@ -50,7 +50,7 @@ class GetVBuilder { auto [cur_ctx, nxt_ctx] = context_.GetCurAndNextCtxName(); ss += "auto "; ss += (nxt_ctx + " = GetV::get_vertex_from_edges(txn, std::move(" + - cur_ctx + "), " + get_v_params.toString() + + cur_ctx + "), " + get_v_params.to_string() + ", [](size_t){\nreturn true;});\n "); return ss; } diff --git a/flex/engines/graph_db/runtime/codegen/builders/scan_builder.cc b/flex/engines/graph_db/runtime/codegen/builders/scan_builder.cc index 75459a8b8d01..79ea1aa571b2 100644 --- a/flex/engines/graph_db/runtime/codegen/builders/scan_builder.cc +++ b/flex/engines/graph_db/runtime/codegen/builders/scan_builder.cc @@ -1,7 +1,4 @@ #include "flex/engines/graph_db/runtime/codegen/builders/builders.h" -#include "flex/engines/graph_db/runtime/codegen/exprs/expr_utils.h" -#include "flex/engines/graph_db/runtime/codegen/utils/utils.h" -#include "flex/engines/graph_db/runtime/common/utils.h" namespace gs { namespace runtime { @@ -172,12 +169,12 @@ class ScanBuilder { ss += str + "\n auto "; if (scan_oid) { ss += ctx_name + " = Scan::filter_oids(txn, " + - scan_params.toString() + ", [" + name + + scan_params.to_string() + ", [" + name + "](label_t label, vid_t vid){\n return " + name + ".typed_eval_vertex(label, vid, 0);\n" + "}, "; } else { ss += ctx_name + " = Scan::filter_gids(txn, " + - scan_params.toString() + ", [" + name + + scan_params.to_string() + ", [" + name + "](label_t label, vid_t vid){\n return " + name + ".typed_eval_vertex(label, vid, 0);\n" + "}, "; } @@ -186,8 +183,9 @@ class ScanBuilder { } else { std::string ss; ss += str + "\n auto "; - ss += ctx_name + " = Scan::scan_vertex(txn, " + scan_params.toString() + - ", [" + name + "](label_t label, vid_t vid){\n return " + name + + ss += ctx_name + " = Scan::scan_vertex(txn, " + + scan_params.to_string() + ", [" + name + + "](label_t label, vid_t vid){\n return " + name + ".typed_eval_vertex(label, vid, 0);\n" + "});\n"; return ss; } @@ -201,13 +199,14 @@ class ScanBuilder { if (scan_oid) { std::string ss{"auto "}; - ss += ctx_name + " = Scan::filter_oids(txn, " + scan_params.toString() + - "[](label_t label, vid_t vid){\n" + "return true;\n" + "}, " + - vec_2_str(oids) + ");\n"; + ss += ctx_name + " = Scan::filter_oids(txn, " + + scan_params.to_string() + "[](label_t label, vid_t vid){\n" + + "return true;\n" + "}, " + vec_2_str(oids) + ");\n"; return ss; } else { std::string ss{"auto "}; - ss += ctx_name + " = Scan::filter_gids(txn, " + scan_params.toString() + + ss += ctx_name + " = Scan::filter_gids(txn, " + + scan_params.to_string() + "[](label_t label, vid_t vid){\n return true;\n" + "}, " + vec_2_str(oids) + ");\n"; return ss; @@ -215,7 +214,7 @@ class ScanBuilder { } else { std::string ss{"auto "}; - ss += ctx_name + " = Scan::scan_vertex(txn, " + scan_params.toString() + + ss += ctx_name + " = Scan::scan_vertex(txn, " + scan_params.to_string() + "[](label_t label, vid_t vid){\n return true;\n});\n"; return ss; } diff --git a/flex/engines/graph_db/runtime/codegen/builders/select_builder.cc b/flex/engines/graph_db/runtime/codegen/builders/select_builder.cc new file mode 100644 index 000000000000..57953d5c48fe --- /dev/null +++ b/flex/engines/graph_db/runtime/codegen/builders/select_builder.cc @@ -0,0 +1,24 @@ +#include "flex/engines/graph_db/runtime/codegen/builders/builders.h" +namespace gs { +namespace runtime { +class SelectBuilder { + public: + SelectBuilder(BuildingContext& context) : context_(context) {}; + std::string Build(const algebra::Select& opr) { + auto [expr_name, expr_str] = + build_expr(context_, opr.predicate(), VarType::kPathVar); + std::string ss; + auto [cur_ctx, nxt_ctx] = context_.GetCurAndNextCtxName(); + ss += "auto "; + ss += (nxt_ctx + " = Select::select(" + cur_ctx + ", PathPredicate(" + + expr_name + "));\n"); + return ss; + } + BuildingContext& context_; +}; +std::string build_select(BuildingContext& context, const algebra::Select& opr) { + SelectBuilder builder(context); + return builder.Build(opr); +} +} // namespace runtime +} // namespace gs \ No newline at end of file diff --git a/flex/engines/graph_db/runtime/codegen/codegen.cc b/flex/engines/graph_db/runtime/codegen/codegen.cc index 26d1943f6003..715dfacb58f1 100644 --- a/flex/engines/graph_db/runtime/codegen/codegen.cc +++ b/flex/engines/graph_db/runtime/codegen/codegen.cc @@ -31,6 +31,14 @@ class Codegen { ss += build_get_v(context, opr.opr().vertex()); LOG(INFO) << ss; break; + case physical::PhysicalOpr_Operator::OpKindCase::kEdge: + ss += build_edge_expand(context, opr.opr().edge(), opr.meta_data(0)); + LOG(INFO) << ss; + break; + + case physical::PhysicalOpr_Operator::OpKindCase::kSelect: + ss += build_select(context, opr.opr().select()); + break; default: break; diff --git a/flex/engines/graph_db/runtime/codegen/exprs/static_expr.h b/flex/engines/graph_db/runtime/codegen/exprs/static_expr.h index d50df4609715..3094c59a6fe3 100644 --- a/flex/engines/graph_db/runtime/codegen/exprs/static_expr.h +++ b/flex/engines/graph_db/runtime/codegen/exprs/static_expr.h @@ -20,6 +20,20 @@ namespace gs { namespace runtime { +template +class is_optional_test { + private: + template + static auto test(int) -> decltype(std::declval().is_optional(), + std::true_type()); + + template + static std::false_type test(...); + + public: + static constexpr bool value = decltype(test(0))::value; +}; + template struct UnaryOpExpr { UnaryOpExpr(const EXPR& expr, OP&& op) : expr_(expr), op_(op) {} @@ -300,6 +314,19 @@ struct PathPredicate { return expr_.typed_eval_path(path_idx); } + bool is_optional() const { + return is_optional_test::value && expr_.is_optional(); + } + + bool operator()(size_t path_idx, int) const { + // typed_eval_path(idx, 0) return std::optional + auto val = expr_.typed_eval_path(path_idx, 0); + if (val.has_value()) { + return val.value(); + } + return false; + } + const EXPR& expr_; }; diff --git a/flex/engines/graph_db/runtime/common/operators/edge_expand.h b/flex/engines/graph_db/runtime/common/operators/edge_expand.h index ed1e8bb7feeb..cfb12e08150b 100644 --- a/flex/engines/graph_db/runtime/common/operators/edge_expand.h +++ b/flex/engines/graph_db/runtime/common/operators/edge_expand.h @@ -22,19 +22,13 @@ #include "flex/engines/graph_db/runtime/common/columns/edge_columns.h" #include "flex/engines/graph_db/runtime/common/columns/vertex_columns.h" #include "flex/engines/graph_db/runtime/common/context.h" +#include "flex/engines/graph_db/runtime/common/utils.h" #include "glog/logging.h" namespace gs { namespace runtime { -struct EdgeExpandParams { - int v_tag; - std::vector labels; - int alias; - Direction dir; -}; - class EdgeExpand { public: template diff --git a/flex/engines/graph_db/runtime/common/operators/select.h b/flex/engines/graph_db/runtime/common/operators/select.h index 47a98a7b1eac..136c547e19d7 100644 --- a/flex/engines/graph_db/runtime/common/operators/select.h +++ b/flex/engines/graph_db/runtime/common/operators/select.h @@ -28,9 +28,17 @@ class Select { static void select(Context& ctx, const PRED_T& pred) { size_t row_num = ctx.row_num(); std::vector offsets; - for (size_t k = 0; k < row_num; ++k) { - if (pred(k)) { - offsets.push_back(k); + if (pred.is_optional()) { + for (size_t k = 0; k < row_num; ++k) { + if (pred(k, 0)) { + offsets.push_back(k); + } + } + } else { + for (size_t k = 0; k < row_num; ++k) { + if (pred(k)) { + offsets.push_back(k); + } } } diff --git a/flex/engines/graph_db/runtime/common/types.h b/flex/engines/graph_db/runtime/common/types.h index 33bd9cd0fed6..8a097925fe80 100644 --- a/flex/engines/graph_db/runtime/common/types.h +++ b/flex/engines/graph_db/runtime/common/types.h @@ -135,9 +135,9 @@ struct LabelTriplet { : src_label(src), dst_label(dst), edge_label(edge) {} std::string to_string() const { - return "(" + std::to_string(static_cast(src_label)) + "-" + - std::to_string(static_cast(edge_label)) + "-" + - std::to_string(static_cast(dst_label)) + ")"; + return "(" + std::to_string(static_cast(src_label)) + "," + + std::to_string(static_cast(dst_label)) + "," + + std::to_string(static_cast(edge_label)) + ")"; } bool operator==(const LabelTriplet& rhs) const { diff --git a/flex/engines/graph_db/runtime/common/utils.h b/flex/engines/graph_db/runtime/common/utils.h index abefee04a9a4..de64ce21f4da 100644 --- a/flex/engines/graph_db/runtime/common/utils.h +++ b/flex/engines/graph_db/runtime/common/utils.h @@ -25,7 +25,7 @@ struct ScanParams { : alias(alias), tables(tables) {} ScanParams() = default; - std::string toString() const { + std::string to_string() const { std::stringstream ss; ss << "ScanParams(" << alias << ", "; ss << "{"; @@ -49,7 +49,7 @@ struct GetVParams { GetVParams(VOpt opt, int tag, const std::vector& tables, int alias) : opt(opt), tag(tag), tables(tables), alias(alias) {} GetVParams() = default; - std::string toString() const { + std::string to_string() const { std::stringstream ss; ss << "GetVParams(" << vopt_2_str(opt) << ", " << tag << ", "; ss << "{"; @@ -65,6 +65,33 @@ struct GetVParams { } }; +struct EdgeExpandParams { + int v_tag; + std::vector labels; + int alias; + Direction dir; + + EdgeExpandParams(int v_tag, const std::vector& labels, + int alias, Direction dir) + : v_tag(v_tag), labels(labels), alias(alias), dir(dir) {} + EdgeExpandParams() = default; + + std::string to_string() const { + std::stringstream ss; + ss << "EdgeExpandParams(" << v_tag << ", "; + ss << "{"; + for (size_t i = 0; i < labels.size(); ++i) { + if (i + 1 == labels.size()) { + ss << "LabelTriplet" << labels[i].to_string(); + } else { + ss << "LabelTriplet" << labels[i].to_string() << ", "; + } + } + ss << "}, " << alias << ", " << dir_2_str(dir) << ")"; + return ss.str(); + } +}; + } // namespace runtime } // namespace gs