From a4025d7a25d949cfeefeb81758c22d5667415d47 Mon Sep 17 00:00:00 2001 From: "xiaolei.zl" Date: Thu, 12 Sep 2024 19:50:03 +0800 Subject: [PATCH] add error handling for expression parsing, fix the support for getting edge element id(global_id) Committed-by: xiaolei.zl from Dev container --- flex/engines/graph_db/runtime/adhoc/expr.cc | 15 ++- flex/engines/graph_db/runtime/adhoc/expr.h | 9 +- .../graph_db/runtime/adhoc/expr_impl.cc | 67 ++++++---- .../graph_db/runtime/adhoc/expr_impl.h | 9 +- .../graph_db/runtime/adhoc/operators/dedup.cc | 2 +- .../runtime/adhoc/operators/edge_expand.cc | 3 +- .../graph_db/runtime/adhoc/operators/get_v.cc | 3 +- .../runtime/adhoc/operators/group_by.cc | 40 ++++-- .../runtime/adhoc/operators/order_by.cc | 2 +- .../runtime/adhoc/operators/project.cc | 6 +- .../graph_db/runtime/adhoc/operators/scan.cc | 15 ++- .../runtime/adhoc/operators/select.cc | 3 +- .../graph_db/runtime/adhoc/predicates.h | 40 ++++-- flex/engines/graph_db/runtime/adhoc/var.cc | 119 ++++++++++-------- flex/engines/graph_db/runtime/adhoc/var.h | 6 +- .../graph_db/runtime/common/accessors.cc | 5 + .../graph_db/runtime/common/accessors.h | 70 +++++++++++ .../graph_db/runtime/common/leaf_utils.h | 16 ++- 18 files changed, 297 insertions(+), 133 deletions(-) diff --git a/flex/engines/graph_db/runtime/adhoc/expr.cc b/flex/engines/graph_db/runtime/adhoc/expr.cc index 648f7a108390..888ed15e6f3a 100644 --- a/flex/engines/graph_db/runtime/adhoc/expr.cc +++ b/flex/engines/graph_db/runtime/adhoc/expr.cc @@ -18,11 +18,16 @@ namespace gs { namespace runtime { - -Expr::Expr(const ReadTransaction& txn, const Context& ctx, - const std::map& params, - const common::Expression& expr, VarType var_type) { - expr_ = parse_expression(txn, ctx, params, expr, var_type); +Expr::Expr() : expr_(nullptr) {} + +bl::result Expr::MakeExpr( + const ReadTransaction& txn, const Context& ctx, + const std::map& params, + const common::Expression& expr, VarType var_type) { + Expr expression; + BOOST_LEAF_ASSIGN(expression.expr_, + parse_expression(txn, ctx, params, expr, var_type)); + return expression; } RTAny Expr::eval_path(size_t idx) const { diff --git a/flex/engines/graph_db/runtime/adhoc/expr.h b/flex/engines/graph_db/runtime/adhoc/expr.h index 13cc2eb2d1f0..6df63807dbf5 100644 --- a/flex/engines/graph_db/runtime/adhoc/expr.h +++ b/flex/engines/graph_db/runtime/adhoc/expr.h @@ -18,6 +18,7 @@ #include "flex/engines/graph_db/database/read_transaction.h" #include "flex/engines/graph_db/runtime/adhoc/expr_impl.h" +#include "flex/engines/graph_db/runtime/common/leaf_utils.h" #include "flex/engines/graph_db/runtime/common/rt_any.h" namespace gs { @@ -26,9 +27,11 @@ namespace runtime { class Expr { public: - Expr(const ReadTransaction& txn, const Context& ctx, - const std::map& params, - const common::Expression& expr, VarType var_type); + Expr(); + static bl::result MakeExpr( + const ReadTransaction& txn, const Context& ctx, + const std::map& params, + const common::Expression& expr, VarType var_type); RTAny eval_path(size_t idx) const; RTAny eval_vertex(label_t label, vid_t v, size_t idx) const; diff --git a/flex/engines/graph_db/runtime/adhoc/expr_impl.cc b/flex/engines/graph_db/runtime/adhoc/expr_impl.cc index 7df4cdbeed15..4d6a14cdfb30 100644 --- a/flex/engines/graph_db/runtime/adhoc/expr_impl.cc +++ b/flex/engines/graph_db/runtime/adhoc/expr_impl.cc @@ -21,9 +21,15 @@ namespace gs { namespace runtime { -VariableExpr::VariableExpr(const ReadTransaction& txn, const Context& ctx, - const common::Variable& pb, VarType var_type) - : var_(txn, ctx, pb, var_type) {} +VariableExpr::VariableExpr() {} + +bl::result> VariableExpr::MakeVariableExpr( + const ReadTransaction& txn, const Context& ctx, const common::Variable& pb, + VarType var_type) { + std::unique_ptr expr(new VariableExpr()); + BOOST_LEAF_ASSIGN(expr->var_, Var::MakeVar(txn, ctx, pb, var_type)); + return expr; +} RTAny VariableExpr::eval_path(size_t idx) const { return var_.get(idx); } RTAny VariableExpr::eval_vertex(label_t label, vid_t v, size_t idx) const { return var_.get_vertex(label, v, idx); @@ -512,11 +518,18 @@ static inline int get_proiority(const common::ExprOpr& opr) { } return 16; } -static std::unique_ptr parse_expression_impl( +static bl::result> parse_expression_impl( const ReadTransaction& txn, const Context& ctx, const std::map& params, const common::Expression& expr, VarType var_type); -static std::unique_ptr build_expr( + +bl::result> make_variable_expr( + const ReadTransaction& txn, const Context& ctx, const common::Variable& pb, + VarType var_type) { + return VariableExpr::MakeVariableExpr(txn, ctx, pb, var_type); +} + +static bl::result> build_expr( const ReadTransaction& txn, const Context& ctx, const std::map& params, std::stack& opr_stack, VarType var_type) { @@ -535,7 +548,7 @@ static std::unique_ptr build_expr( return std::make_unique(parse_param(opr.param(), params)); } case common::ExprOpr::kVar: { - return std::make_unique(txn, ctx, opr.var(), var_type); + return make_variable_expr(txn, ctx, opr.var(), var_type); } case common::ExprOpr::kLogical: { if (opr.logical() == common::Logical::WITHIN) { @@ -545,8 +558,7 @@ static std::unique_ptr build_expr( opr_stack.pop(); CHECK(lhs.has_var()); CHECK(rhs.has_const_()); - auto key = - std::make_unique(txn, ctx, lhs.var(), var_type); + BOOST_LEAF_AUTO(key, make_variable_expr(txn, ctx, lhs.var(), var_type)); if (key->type() == RTAnyType::kI64Value) { return std::make_unique>(txn, ctx, std::move(key), rhs.const_()); @@ -561,20 +573,20 @@ static std::unique_ptr build_expr( } } else if (opr.logical() == common::Logical::NOT || opr.logical() == common::Logical::ISNULL) { - auto lhs = build_expr(txn, ctx, params, opr_stack, var_type); + BOOST_LEAF_AUTO(lhs, build_expr(txn, ctx, params, opr_stack, var_type)); return std::make_unique(std::move(lhs), opr.logical()); } else { - auto lhs = build_expr(txn, ctx, params, opr_stack, var_type); - auto rhs = build_expr(txn, ctx, params, opr_stack, var_type); + BOOST_LEAF_AUTO(lhs, build_expr(txn, ctx, params, opr_stack, var_type)); + BOOST_LEAF_AUTO(rhs, build_expr(txn, ctx, params, opr_stack, var_type)); return std::make_unique(std::move(lhs), std::move(rhs), opr.logical()); } break; } case common::ExprOpr::kArith: { - auto lhs = build_expr(txn, ctx, params, opr_stack, var_type); - auto rhs = build_expr(txn, ctx, params, opr_stack, var_type); + BOOST_LEAF_AUTO(lhs, build_expr(txn, ctx, params, opr_stack, var_type)); + BOOST_LEAF_AUTO(rhs, build_expr(txn, ctx, params, opr_stack, var_type)); return std::make_unique(std::move(lhs), std::move(rhs), opr.arith()); } @@ -587,25 +599,29 @@ static std::unique_ptr build_expr( for (size_t i = 0; i < len; ++i) { auto when_expr = op.when_then_expressions(i).when_expression(); auto then_expr = op.when_then_expressions(i).then_result_expression(); - when_then_exprs.emplace_back( - parse_expression_impl(txn, ctx, params, when_expr, var_type), - parse_expression_impl(txn, ctx, params, then_expr, var_type)); + BOOST_LEAF_AUTO( + when, parse_expression_impl(txn, ctx, params, when_expr, var_type)); + BOOST_LEAF_AUTO( + then, parse_expression_impl(txn, ctx, params, then_expr, var_type)); + when_then_exprs.emplace_back(std::move(when), std::move(then)); } - auto else_expr = parse_expression_impl( - txn, ctx, params, op.else_result_expression(), var_type); + BOOST_LEAF_AUTO(else_expr, parse_expression_impl( + txn, ctx, params, + op.else_result_expression(), var_type)); return std::make_unique(std::move(when_then_exprs), std::move(else_expr)); } case common::ExprOpr::kExtract: { - auto hs = build_expr(txn, ctx, params, opr_stack, var_type); + BOOST_LEAF_AUTO(hs, build_expr(txn, ctx, params, opr_stack, var_type)); return std::make_unique(std::move(hs), opr.extract()); } case common::ExprOpr::kVars: { auto op = opr.vars(); std::vector> exprs; for (int i = 0; i < op.keys_size(); ++i) { - exprs.push_back( - std::make_unique(txn, ctx, op.keys(i), var_type)); + BOOST_LEAF_AUTO(expr, + make_variable_expr(txn, ctx, op.keys(i), var_type)); + exprs.push_back(std::move(expr)); } return std::make_unique(std::move(exprs)); // LOG(FATAL) << "not support" << opr.DebugString(); @@ -624,9 +640,8 @@ static std::unique_ptr build_expr( auto str = any.as_string(); keys_vec.push_back(std::string(str)); } - exprs.emplace_back( - std::make_unique(txn, ctx, val, - var_type)); // just for parse + BOOST_LEAF_AUTO(expr, make_variable_expr(txn, ctx, val, var_type)); + exprs.push_back(std::move(expr)); } if (exprs.size() > 0) { return std::make_unique(std::move(keys_vec), std::move(exprs)); @@ -640,7 +655,7 @@ static std::unique_ptr build_expr( } return nullptr; } -static std::unique_ptr parse_expression_impl( +static bl::result> parse_expression_impl( const ReadTransaction& txn, const Context& ctx, const std::map& params, const common::Expression& expr, VarType var_type) { @@ -712,7 +727,7 @@ static std::unique_ptr parse_expression_impl( } return build_expr(txn, ctx, params, opr_stack2, var_type); } -std::unique_ptr parse_expression( +bl::result> parse_expression( const ReadTransaction& txn, const Context& ctx, const std::map& params, const common::Expression& expr, VarType var_type) { diff --git a/flex/engines/graph_db/runtime/adhoc/expr_impl.h b/flex/engines/graph_db/runtime/adhoc/expr_impl.h index 20a764de0696..83536e7f759b 100644 --- a/flex/engines/graph_db/runtime/adhoc/expr_impl.h +++ b/flex/engines/graph_db/runtime/adhoc/expr_impl.h @@ -19,6 +19,7 @@ #include "flex/proto_generated_gie/expr.pb.h" #include "flex/engines/graph_db/runtime/adhoc/var.h" +#include "flex/engines/graph_db/runtime/common/leaf_utils.h" #include "flex/engines/graph_db/runtime/common/rt_any.h" namespace gs { @@ -171,8 +172,10 @@ class WithInExpr : public ExprBase { class VariableExpr : public ExprBase { public: - VariableExpr(const ReadTransaction& txn, const Context& ctx, - const common::Variable& pb, VarType var_type); + VariableExpr(); + static bl::result> MakeVariableExpr( + const ReadTransaction& txn, const Context& ctx, + const common::Variable& pb, VarType var_type); RTAny eval_path(size_t idx) const override; RTAny eval_vertex(label_t label, vid_t v, size_t idx) const override; @@ -399,7 +402,7 @@ class MapExpr : public ExprBase { std::vector> value_exprs; mutable std::vector> values; }; -std::unique_ptr parse_expression( +bl::result> parse_expression( const ReadTransaction& txn, const Context& ctx, const std::map& params, const common::Expression& expr, VarType var_type); diff --git a/flex/engines/graph_db/runtime/adhoc/operators/dedup.cc b/flex/engines/graph_db/runtime/adhoc/operators/dedup.cc index 0e5470b8fce4..cf4d45203198 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/dedup.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/dedup.cc @@ -35,7 +35,7 @@ bl::result eval_dedup(const algebra::Dedup& opr, tag = key.tag().id(); } if (key.has_property()) { - Var var(txn, ctx, key, VarType::kPathVar); + BOOST_LEAF_AUTO(var, Var::MakeVar(txn, ctx, key, VarType::kPathVar)); vars.emplace_back([var](size_t i) { return var.get(i); }); flag = true; } else { diff --git a/flex/engines/graph_db/runtime/adhoc/operators/edge_expand.cc b/flex/engines/graph_db/runtime/adhoc/operators/edge_expand.cc index c0e75d69cd40..06939a36999d 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/edge_expand.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/edge_expand.cc @@ -70,7 +70,8 @@ bl::result eval_edge_expand( eep.dir = dir; eep.alias = alias; - GeneralEdgePredicate pred(txn, ctx, params, query_params.predicate()); + BOOST_LEAF_AUTO(pred, GeneralEdgePredicate::MakeGeneralEdgePredicate( + txn, ctx, params, query_params.predicate())); return EdgeExpand::expand_edge(txn, std::move(ctx), eep, pred); } else { diff --git a/flex/engines/graph_db/runtime/adhoc/operators/get_v.cc b/flex/engines/graph_db/runtime/adhoc/operators/get_v.cc index c1e18a10fc6a..0526b4d14584 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/get_v.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/get_v.cc @@ -60,7 +60,8 @@ bl::result eval_get_v( p.tables = parse_tables(query_params); p.alias = alias; if (query_params.has_predicate()) { - GeneralVertexPredicate pred(txn, ctx, params, query_params.predicate()); + BOOST_LEAF_AUTO(pred, GeneralVertexPredicate::MakeGeneralVertexPredicate( + txn, ctx, params, query_params.predicate())); if (opt == VOpt::kItself) { return GetV::get_vertex_from_vertices(txn, std::move(ctx), p, pred); diff --git a/flex/engines/graph_db/runtime/adhoc/operators/group_by.cc b/flex/engines/graph_db/runtime/adhoc/operators/group_by.cc index 14f070759c1e..6f11cf07d99d 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/group_by.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/group_by.cc @@ -62,16 +62,25 @@ AggrKind parse_aggregate(physical::GroupBy_AggFunc::Aggregate v) { } struct AggFunc { - AggFunc(const physical::GroupBy_AggFunc& opr, const ReadTransaction& txn, - const Context& ctx) - : aggregate(parse_aggregate(opr.aggregate())), alias(-1) { + AggFunc() : alias(-1) {} + + static bl::result MakeAggFunc(const physical::GroupBy_AggFunc& opr, + const ReadTransaction& txn, + const Context& ctx) { + AggFunc agg_func; + agg_func.aggregate = parse_aggregate(opr.aggregate()); + if (opr.has_alias()) { - alias = opr.alias().value(); + agg_func.alias = opr.alias().value(); } int var_num = opr.vars_size(); for (int i = 0; i < var_num; ++i) { - vars.emplace_back(txn, ctx, opr.vars(i), VarType::kPathVar); + // vars.emplace_back(txn, ctx, opr.vars(i), VarType::kPathVar); + BOOST_LEAF_AUTO(var, + Var::MakeVar(txn, ctx, opr.vars(i), VarType::kPathVar)); + agg_func.vars.push_back(std::move(var)); } + return agg_func; } std::vector vars; @@ -80,12 +89,15 @@ struct AggFunc { }; struct AggKey { - AggKey(const physical::GroupBy_KeyAlias& opr, const ReadTransaction& txn, - const Context& ctx) - : key(txn, ctx, opr.key(), VarType::kPathVar), alias(-1) { - if (opr.has_alias()) { - alias = opr.alias().value(); - } + AggKey() : alias(-1) {} + static bl::result MakeAggKey(const physical::GroupBy_KeyAlias& opr, + const ReadTransaction& txn, + const Context& ctx) { + AggKey agg_key; + BOOST_LEAF_ASSIGN(agg_key.key, + Var::MakeVar(txn, ctx, opr.key(), VarType::kPathVar)); + agg_key.alias = opr.alias().value(); + return agg_key; } Var key; @@ -536,7 +548,8 @@ bl::result eval_group_by(const physical::GroupBy& opr, std::vector mappings; int func_num = opr.functions_size(); for (int i = 0; i < func_num; ++i) { - functions.emplace_back(opr.functions(i), txn, ctx); + BOOST_LEAF_AUTO(func, AggFunc::MakeAggFunc(opr.functions(i), txn, ctx)); + functions.emplace_back(std::move(func)); } int mappings_num = opr.mappings_size(); @@ -556,7 +569,8 @@ bl::result eval_group_by(const physical::GroupBy& opr, return ret; } else { for (int i = 0; i < mappings_num; ++i) { - mappings.emplace_back(opr.mappings(i), txn, ctx); + BOOST_LEAF_AUTO(key, AggKey::MakeAggKey(opr.mappings(i), txn, ctx)); + mappings.emplace_back(std::move(key)); } auto keys_ret = diff --git a/flex/engines/graph_db/runtime/adhoc/operators/order_by.cc b/flex/engines/graph_db/runtime/adhoc/operators/order_by.cc index 2e85ef0607f1..47ecfab995d2 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/order_by.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/order_by.cc @@ -70,7 +70,7 @@ bl::result eval_order_by(const algebra::OrderBy& opr, int keys_num = opr.pairs_size(); for (int i = 0; i < keys_num; ++i) { const algebra::OrderBy_OrderingPair& pair = opr.pairs(i); - Var v(txn, ctx, pair.key(), VarType::kPathVar); + BOOST_LEAF_AUTO(v, Var::MakeVar(txn, ctx, pair.key(), VarType::kPathVar)); CHECK(pair.order() == algebra::OrderBy_OrderingPair_Order:: OrderBy_OrderingPair_Order_ASC || pair.order() == algebra::OrderBy_OrderingPair_Order:: diff --git a/flex/engines/graph_db/runtime/adhoc/operators/project.cc b/flex/engines/graph_db/runtime/adhoc/operators/project.cc index 3c372aef709c..c95180b72ae2 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/project.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/project.cc @@ -65,7 +65,8 @@ bl::result eval_project( continue; } } - Expr expr(txn, ctx, params, m.expr(), VarType::kPathVar); + BOOST_LEAF_AUTO( + expr, Expr::MakeExpr(txn, ctx, params, m.expr(), VarType::kPathVar)); int alias = -1; if (m.has_alias()) { alias = m.alias().value(); @@ -86,7 +87,8 @@ bl::result eval_project( } } - Expr expr(txn, ctx, params, m.expr(), VarType::kPathVar); + BOOST_LEAF_AUTO( + expr, Expr::MakeExpr(txn, ctx, params, m.expr(), VarType::kPathVar)); int alias = -1; if (m.has_alias()) { alias = m.alias().value(); diff --git a/flex/engines/graph_db/runtime/adhoc/operators/scan.cc b/flex/engines/graph_db/runtime/adhoc/operators/scan.cc index d9cff3bfa4de..0a2181f4ab45 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/scan.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/scan.cc @@ -269,8 +269,9 @@ bl::result eval_scan( if (!has_other_type_oid && scan_opr.has_idx_predicate()) { if (scan_opr.has_idx_predicate() && scan_opr_params.has_predicate()) { Context ctx; - auto expr = parse_expression( - txn, ctx, params, scan_opr_params.predicate(), VarType::kVertexVar); + BOOST_LEAF_AUTO(expr, parse_expression(txn, ctx, params, + scan_opr_params.predicate(), + VarType::kVertexVar)); std::vector oids{}; if (!parse_idx_predicate(scan_opr.idx_predicate(), params, oids, scan_oid)) { @@ -309,8 +310,9 @@ bl::result eval_scan( } else if (scan_opr.has_idx_predicate()) { if (scan_opr.has_idx_predicate() && scan_opr_params.has_predicate()) { Context ctx; - auto expr = parse_expression( - txn, ctx, params, scan_opr_params.predicate(), VarType::kVertexVar); + BOOST_LEAF_AUTO(expr, parse_expression(txn, ctx, params, + scan_opr_params.predicate(), + VarType::kVertexVar)); std::vector oids{}; if (!parse_idx_predicate(scan_opr.idx_predicate(), params, oids, scan_oid)) { @@ -336,8 +338,9 @@ bl::result eval_scan( if (scan_opr_params.has_predicate()) { Context ctx; - auto expr = parse_expression( - txn, ctx, params, scan_opr_params.predicate(), VarType::kVertexVar); + BOOST_LEAF_AUTO( + expr, parse_expression(txn, ctx, params, scan_opr_params.predicate(), + VarType::kVertexVar)); if (expr->is_optional()) { return Scan::scan_vertex( txn, scan_params, [&expr](label_t label, vid_t vid) { diff --git a/flex/engines/graph_db/runtime/adhoc/operators/select.cc b/flex/engines/graph_db/runtime/adhoc/operators/select.cc index 0d786c224789..64b6fd890e1d 100644 --- a/flex/engines/graph_db/runtime/adhoc/operators/select.cc +++ b/flex/engines/graph_db/runtime/adhoc/operators/select.cc @@ -23,7 +23,8 @@ namespace runtime { bl::result eval_select( const algebra::Select& opr, const ReadTransaction& txn, Context&& ctx, const std::map& params) { - Expr expr(txn, ctx, params, opr.predicate(), VarType::kPathVar); + BOOST_LEAF_AUTO(expr, Expr::MakeExpr(txn, ctx, params, opr.predicate(), + VarType::kPathVar)); std::vector offsets; size_t row_num = ctx.row_num(); if (expr.is_optional()) { diff --git a/flex/engines/graph_db/runtime/adhoc/predicates.h b/flex/engines/graph_db/runtime/adhoc/predicates.h index 560ffc9c40b7..f0e81a7871a5 100644 --- a/flex/engines/graph_db/runtime/adhoc/predicates.h +++ b/flex/engines/graph_db/runtime/adhoc/predicates.h @@ -19,6 +19,7 @@ #include "flex/engines/graph_db/runtime/adhoc/expr.h" #include "flex/engines/graph_db/runtime/adhoc/var.h" #include "flex/engines/graph_db/runtime/common/context.h" +#include "flex/engines/graph_db/runtime/common/leaf_utils.h" #include "flex/proto_generated_gie/expr.pb.h" namespace gs { @@ -26,10 +27,15 @@ namespace gs { namespace runtime { struct GeneralPathPredicate { - GeneralPathPredicate(const ReadTransaction& txn, const Context& ctx, - const std::map& params, - const common::Expression& expr) - : expr_(txn, ctx, params, expr, VarType::kPathVar) {} + GeneralPathPredicate(Expr&& expr) : expr_(std::move(expr)) {} + static bl::result MakeGeneralPathPredicate( + const ReadTransaction& txn, const Context& ctx, + const std::map& params, + const common::Expression& expr) { + BOOST_LEAF_AUTO(expression, + Expr::MakeExpr(txn, ctx, params, expr, VarType::kPathVar)); + return GeneralPathPredicate(std::move(expression)); + } bool operator()(size_t idx) const { auto val = expr_.eval_path(idx); @@ -40,10 +46,15 @@ struct GeneralPathPredicate { }; struct GeneralVertexPredicate { - GeneralVertexPredicate(const ReadTransaction& txn, const Context& ctx, - const std::map& params, - const common::Expression& expr) - : expr_(txn, ctx, params, expr, VarType::kVertexVar) {} + GeneralVertexPredicate(Expr&& expr) : expr_(std::move(expr)) {} + static bl::result MakeGeneralVertexPredicate( + const ReadTransaction& txn, const Context& ctx, + const std::map& params, + const common::Expression& expr) { + BOOST_LEAF_AUTO(expression, Expr::MakeExpr(txn, ctx, params, expr, + VarType::kVertexVar)); + return GeneralVertexPredicate(std::move(expression)); + } bool operator()(label_t label, vid_t v, size_t path_idx) const { auto val = expr_.eval_vertex(label, v, path_idx); @@ -54,10 +65,15 @@ struct GeneralVertexPredicate { }; struct GeneralEdgePredicate { - GeneralEdgePredicate(const ReadTransaction& txn, const Context& ctx, - const std::map& params, - const common::Expression& expr) - : expr_(txn, ctx, params, expr, VarType::kEdgeVar) {} + GeneralEdgePredicate(Expr&& expr) : expr_(std::move(expr)) {} + static bl::result MakeGeneralEdgePredicate( + const ReadTransaction& txn, const Context& ctx, + const std::map& params, + const common::Expression& expr) { + BOOST_LEAF_AUTO(expression, + Expr::MakeExpr(txn, ctx, params, expr, VarType::kEdgeVar)); + return GeneralEdgePredicate(std::move(expression)); + } bool operator()(const LabelTriplet& label, vid_t src, vid_t dst, const Any& edata, Direction dir, size_t path_idx) const { diff --git a/flex/engines/graph_db/runtime/adhoc/var.cc b/flex/engines/graph_db/runtime/adhoc/var.cc index 96da98e8abaf..fe99b400dd02 100644 --- a/flex/engines/graph_db/runtime/adhoc/var.cc +++ b/flex/engines/graph_db/runtime/adhoc/var.cc @@ -23,27 +23,28 @@ namespace gs { namespace runtime { -Var::Var(const ReadTransaction& txn, const Context& ctx, - const common::Variable& pb, VarType var_type) - : getter_(nullptr) { +Var::Var() : getter_(nullptr) {} +bl::result Var::MakeVar(const ReadTransaction& txn, const Context& ctx, + const common::Variable& pb, VarType var_type) { + Var var; int tag = -1; - type_ = RTAnyType::kUnknown; + var.type_ = RTAnyType::kUnknown; if (pb.has_node_type()) { - type_ = parse_from_ir_data_type(pb.node_type()); + var.type_ = parse_from_ir_data_type(pb.node_type()); } if (pb.has_tag()) { tag = pb.tag().id(); } - if (type_ == RTAnyType::kUnknown) { + if (var.type_ == RTAnyType::kUnknown) { if (pb.has_tag()) { tag = pb.tag().id(); CHECK(ctx.get(tag) != nullptr); - type_ = ctx.get(tag)->elem_type(); + var.type_ = ctx.get(tag)->elem_type(); } else if (pb.has_property() && pb.property().has_label()) { - type_ = RTAnyType::kI64Value; + var.type_ = RTAnyType::kI64Value; } else { - LOG(FATAL) << "not support"; + RETURN_UNSUPPORTED_ERROR("not support for var: " + pb.DebugString()); } } @@ -53,117 +54,133 @@ Var::Var(const ReadTransaction& txn, const Context& ctx, if (pb.has_property()) { auto& pt = pb.property(); if (pt.has_id()) { - getter_ = std::make_shared(ctx, tag); + var.getter_ = std::make_shared(ctx, tag); } else if (pt.has_key()) { if (pt.key().name() == "id") { - if (type_ == RTAnyType::kStringValue) { - getter_ = + if (var.type_ == RTAnyType::kStringValue) { + var.getter_ = std::make_shared>( txn, ctx, tag); - } else if (type_ == RTAnyType::kI32Value) { - getter_ = std::make_shared>( + } else if (var.type_ == RTAnyType::kI32Value) { + var.getter_ = std::make_shared>( txn, ctx, tag); - } else if (type_ == RTAnyType::kI64Value) { - getter_ = std::make_shared>( + } else if (var.type_ == RTAnyType::kI64Value) { + var.getter_ = std::make_shared>( txn, ctx, tag); } else { - LOG(FATAL) << "not support for " - << static_cast(type_.type_enum_); + RETURN_UNSUPPORTED_ERROR( + "not support for " + + std::to_string(static_cast(var.type_.type_enum_))); } } else { - getter_ = create_vertex_property_path_accessor(txn, ctx, tag, type_, - pt.key().name()); + var.getter_ = create_vertex_property_path_accessor( + txn, ctx, tag, var.type_, pt.key().name()); } } else if (pt.has_label()) { - getter_ = create_vertex_label_path_accessor(ctx, tag); + var.getter_ = create_vertex_label_path_accessor(ctx, tag); } else { - LOG(FATAL) << "xxx, " << pt.item_case(); + RETURN_UNSUPPORTED_ERROR("Supported property for vertex : " + + pt.DebugString()); } } else { - getter_ = std::make_shared(ctx, tag); + var.getter_ = std::make_shared(ctx, tag); } } else if (ctx.get(tag)->column_type() == ContextColumnType::kValue || ctx.get(tag)->column_type() == ContextColumnType::kOptionalValue) { - getter_ = create_context_value_accessor(ctx, tag, type_); + var.getter_ = create_context_value_accessor(ctx, tag, var.type_); } else if (ctx.get(tag)->column_type() == ContextColumnType::kEdge) { if (pb.has_property()) { auto& pt = pb.property(); if (pt.has_key()) { auto name = pt.key().name(); - getter_ = - create_edge_property_path_accessor(txn, name, ctx, tag, type_); + var.getter_ = create_edge_property_path_accessor(txn, name, ctx, tag, + var.type_); } else if (pt.has_label()) { - getter_ = create_edge_label_path_accessor(ctx, tag); + var.getter_ = create_edge_label_path_accessor(ctx, tag); + } else if (pt.has_id()) { + var.getter_ = create_edge_global_id_path_accessor(ctx, tag); } else { - LOG(FATAL) << "not support..."; + RETURN_UNSUPPORTED_ERROR("Supported property for edge: " + + pt.DebugString()); } } else { - getter_ = std::make_shared(ctx, tag); + var.getter_ = std::make_shared(ctx, tag); // LOG(FATAL) << "not support for edge column - " << tag; } } else if (ctx.get(tag)->column_type() == ContextColumnType::kPath) { if (pb.has_property()) { auto& pt = pb.property(); if (pt.has_len()) { - getter_ = std::make_shared(ctx, tag); + var.getter_ = std::make_shared(ctx, tag); } else { - LOG(FATAL) << "not support for path column - " << pt.DebugString(); + RETURN_UNSUPPORTED_ERROR("Supported property for path: " + + pt.DebugString()); } } else { - getter_ = std::make_shared(ctx, tag); + var.getter_ = std::make_shared(ctx, tag); } } else { - LOG(FATAL) << "not support for " << ctx.get(tag)->column_info(); + RETURN_UNSUPPORTED_ERROR( + "not support for column type: " + + std::to_string(static_cast(ctx.get(tag)->column_type()))); } } else { if (var_type == VarType::kVertexVar) { if (pb.has_property()) { auto& pt = pb.property(); if (pt.has_id()) { - getter_ = std::make_shared(); + var.getter_ = std::make_shared(); } else if (pt.has_key()) { if (pt.key().name() == "id") { - if (type_ == RTAnyType::kStringValue) { - getter_ = + if (var.type_ == RTAnyType::kStringValue) { + var.getter_ = std::make_shared>( txn); - } else if (type_ == RTAnyType::kI32Value) { - getter_ = std::make_shared>(txn); - } else if (type_ == RTAnyType::kI64Value) { - getter_ = std::make_shared>(txn); + } else if (var.type_ == RTAnyType::kI32Value) { + var.getter_ = + std::make_shared>(txn); + } else if (var.type_ == RTAnyType::kI64Value) { + var.getter_ = + std::make_shared>(txn); } else { - LOG(FATAL) << "not support for " - << static_cast(type_.type_enum_); + RETURN_UNSUPPORTED_ERROR( + "not support for " + + std::to_string(static_cast(var.type_.type_enum_))); } } else { - getter_ = create_vertex_property_vertex_accessor(txn, type_, - pt.key().name()); + var.getter_ = create_vertex_property_vertex_accessor( + txn, var.type_, pt.key().name()); } } else if (pt.has_label()) { - getter_ = std::make_shared(); + var.getter_ = std::make_shared(); } else { - LOG(FATAL) << "xxx, " << pt.item_case(); + RETURN_UNSUPPORTED_ERROR("Supported property for vertex : " + + pt.DebugString()); } } else { - LOG(FATAL) << "not support"; + RETURN_UNSUPPORTED_ERROR("not support for vertex var with no property"); } } else if (var_type == VarType::kEdgeVar) { if (pb.has_property()) { auto& pt = pb.property(); if (pt.has_key()) { auto name = pt.key().name(); - getter_ = create_edge_property_edge_accessor(txn, name, type_); + var.getter_ = + create_edge_property_edge_accessor(txn, name, var.type_); } else { - LOG(FATAL) << "not support"; + RETURN_UNSUPPORTED_ERROR("Supported property for edge: " + + pt.DebugString()); } } else { - LOG(FATAL) << "not support"; + RETURN_UNSUPPORTED_ERROR("not support for edge var with no property"); } } else { - LOG(FATAL) << "not support"; + RETURN_UNSUPPORTED_ERROR("not support for var type: " + + std::to_string(static_cast(var_type))); } } + return var; } Var::~Var() {} diff --git a/flex/engines/graph_db/runtime/adhoc/var.h b/flex/engines/graph_db/runtime/adhoc/var.h index a209e49b4a24..2709ca2dd3b2 100644 --- a/flex/engines/graph_db/runtime/adhoc/var.h +++ b/flex/engines/graph_db/runtime/adhoc/var.h @@ -20,6 +20,7 @@ #include "flex/engines/graph_db/runtime/common/accessors.h" #include "flex/engines/graph_db/runtime/common/context.h" +#include "flex/engines/graph_db/runtime/common/leaf_utils.h" #include "flex/proto_generated_gie/expr.pb.h" @@ -45,8 +46,9 @@ class VarGetterBase { class Var { public: - Var(const ReadTransaction& txn, const Context& ctx, - const common::Variable& pb, VarType var_type); + static bl::result MakeVar(const ReadTransaction& txn, const Context& ctx, + const common::Variable& pb, VarType var_type); + Var(); ~Var(); RTAny get(size_t path_idx) const; diff --git a/flex/engines/graph_db/runtime/common/accessors.cc b/flex/engines/graph_db/runtime/common/accessors.cc index 55712fc1bb72..a2db2d284d81 100644 --- a/flex/engines/graph_db/runtime/common/accessors.cc +++ b/flex/engines/graph_db/runtime/common/accessors.cc @@ -175,6 +175,11 @@ std::shared_ptr create_edge_label_path_accessor(const Context& ctx, return std::make_shared(ctx, tag); } +std::shared_ptr create_edge_global_id_path_accessor( + const Context& ctx, int tag) { + return std::make_shared(ctx, tag); +} + std::shared_ptr create_edge_property_edge_accessor( const ReadTransaction& txn, const std::string& prop_name, RTAnyType type) { bool multip_properties = txn.schema().has_multi_props_edge(); diff --git a/flex/engines/graph_db/runtime/common/accessors.h b/flex/engines/graph_db/runtime/common/accessors.h index dd3f87cc7c99..549cf9a8d874 100644 --- a/flex/engines/graph_db/runtime/common/accessors.h +++ b/flex/engines/graph_db/runtime/common/accessors.h @@ -398,6 +398,73 @@ class EdgeIdPathAccessor : public IAccessor { const IEdgeColumn& edge_col_; }; +// Access the global edge id of an edge in a path +// Currently we have no unique id for a edge. +// We construct the id from the edge's src, dst and label. +class EdgeGlobalIdPathAccessor : public IAccessor { + public: + using elem_t = int64_t; // edge global id + EdgeGlobalIdPathAccessor(const Context& ctx, int tag) + : edge_col_(*std::dynamic_pointer_cast(ctx.get(tag))) {} + + static uint32_t generate_edge_label_id(label_t src_label_id, + label_t dst_label_id, + label_t edge_label_id) { + uint32_t unique_edge_label_id = src_label_id; + static constexpr int num_bits = sizeof(label_t) * 8; + unique_edge_label_id = unique_edge_label_id << num_bits; + unique_edge_label_id = unique_edge_label_id | dst_label_id; + unique_edge_label_id = unique_edge_label_id << num_bits; + unique_edge_label_id = unique_edge_label_id | edge_label_id; + return unique_edge_label_id; + } + + static int64_t encode_unique_edge_id(uint32_t label_id, vid_t src, + vid_t dst) { + // We assume label_id is only used by 24 bits. + int64_t unique_edge_id = label_id; + unique_edge_id = unique_edge_id << 40; + // bitmask for top 40 bits set to 1 + int64_t bitmask = 0xFFFFFFFFFF000000; + // 24 bit | 20 bit | 20 bit + if (bitmask & (int64_t) src || bitmask & (int64_t) dst) { + LOG(ERROR) << "src or dst is too large to be encoded in 20 bits: " << src + << " " << dst; + } + unique_edge_id = unique_edge_id | (src << 20); + unique_edge_id = unique_edge_id | dst; + return unique_edge_id; + } + + elem_t typed_eval_path(size_t idx) const { + const auto& e = edge_col_.get_edge(idx); + auto label_id = generate_edge_label_id(std::get<0>(e).src_label, + std::get<0>(e).dst_label, + std::get<0>(e).edge_label); + return encode_unique_edge_id(label_id, std::get<1>(e), std::get<2>(e)); + } + + RTAny eval_path(size_t idx) const override { + return RTAny::from_int64(typed_eval_path(idx)); + } + + bool is_optional() const override { return edge_col_.is_optional(); } + + RTAny eval_path(size_t idx, int) const override { + if (!edge_col_.has_value(idx)) { + return RTAny(RTAnyType::kNull); + } + return RTAny::from_int64(typed_eval_path(idx)); + } + + std::shared_ptr builder() const override { + return edge_col_.builder(); + } + + private: + const IEdgeColumn& edge_col_; +}; + template class EdgePropertyPathAccessor : public IAccessor { public: @@ -764,6 +831,9 @@ std::shared_ptr create_edge_property_path_accessor( std::shared_ptr create_edge_label_path_accessor(const Context& ctx, int tag); +std::shared_ptr create_edge_global_id_path_accessor( + const Context& ctx, int tag); + std::shared_ptr create_edge_property_edge_accessor( const ReadTransaction& txn, const std::string& prop_name, RTAnyType type); diff --git a/flex/engines/graph_db/runtime/common/leaf_utils.h b/flex/engines/graph_db/runtime/common/leaf_utils.h index d7bbe69cba15..e5be15bdd415 100644 --- a/flex/engines/graph_db/runtime/common/leaf_utils.h +++ b/flex/engines/graph_db/runtime/common/leaf_utils.h @@ -21,16 +21,22 @@ namespace bl = boost::leaf; -#define RETURN_UNSUPPORTED_ERROR(msg) \ - return ::boost::leaf::new_error( \ - ::gs::Status(::gs::StatusCode::UNSUPPORTED_OPERATION, msg)) +// Concatenate the current function name and line number to form the error +// message +#define PREPEND_LINE_INFO(msg) \ + std::string(__FILE__) + ":" + std::to_string(__LINE__) + \ + " func: " + std::string(__FUNCTION__) + ", " + msg + +#define RETURN_UNSUPPORTED_ERROR(msg) \ + return ::boost::leaf::new_error(::gs::Status( \ + ::gs::StatusCode::UNSUPPORTED_OPERATION, PREPEND_LINE_INFO(msg))) #define RETURN_BAD_REQUEST_ERROR(msg) \ return ::boost::leaf::new_error( \ - ::gs::Status(::gs::StatusCode::BAD_REQUEST, msg)) + ::gs::Status(::gs::StatusCode::BAD_REQUEST, PREPEND_LINE_INFO(msg))) #define RETURN_NOT_IMPLEMENTED_ERROR(msg) \ return ::boost::leaf::new_error( \ - ::gs::Status(::gs::StatusCode::UNIMPLEMENTED, msg)) + ::gs::Status(::gs::StatusCode::UNIMPLEMENTED, PREPEND_LINE_INFO(msg))) #endif // RUNTIME_COMMON_LEAF_UTILS_H_