This is an automated email from the ASF dual-hosted git repository. morningman pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-doris.git
The following commit(s) were added to refs/heads/master by this push: new 1e813df [Doris On ES] [Bug-Fix][Refactor] Fix potential null pointer exception and refactor function process logic (#3985) 1e813df is described below commit 1e813df3fd3b1127d8be9449138fa087f49abc2f Author: Yunfeng,Wu <wuyunfen...@baidu.com> AuthorDate: Thu Jul 2 22:32:16 2020 +0800 [Doris On ES] [Bug-Fix][Refactor] Fix potential null pointer exception and refactor function process logic (#3985) fix: https://github.com/apache/incubator-doris/issues/3984 1. add `conjunct.size` checking and `slot_desc nullptr` checking logic 2. For historical reasons, the function predicates are added one by one, I just refactor the processing make thelogic for function predicate processing more clearly --- be/src/exec/es/es_predicate.cpp | 177 +++++++++++++++++++--------------------- be/src/exec/es/es_predicate.h | 3 +- 2 files changed, 86 insertions(+), 94 deletions(-) diff --git a/be/src/exec/es/es_predicate.cpp b/be/src/exec/es/es_predicate.cpp index 7796201..4c799e1 100644 --- a/be/src/exec/es/es_predicate.cpp +++ b/be/src/exec/es/es_predicate.cpp @@ -226,11 +226,11 @@ static bool is_literal_node(const Expr* expr) { } Status EsPredicate::build_disjuncts_list(const Expr* conjunct) { + // process binary predicate if (TExprNodeType::BINARY_PRED == conjunct->node_type()) { if (conjunct->children().size() != 2) { return Status::InternalError("build disjuncts failed: number of childs is not 2"); } - SlotRef* slot_ref = nullptr; TExprOpcode::type op; Expr* expr = nullptr; @@ -243,7 +243,7 @@ Status EsPredicate::build_disjuncts_list(const Expr* conjunct) { if (TExprNodeType::SLOT_REF == conjunct->get_child(0)->node_type() || TExprNodeType::CAST_EXPR == conjunct->get_child(0)->node_type()) { expr = conjunct->get_child(1); - // process such as sub-query: select * from (select split_part(k, "_", 1) as new_field from case_replay_for_milimin) t where t.new_field > 1; + // process such as sub-query: select * from (select split_part(k, "_", 1) as new_field from table) t where t.new_field > 1; RETURN_ERROR_IF_EXPR_IS_NOT_SLOTREF(conjunct->get_child(0)); // process cast expr, such as: // k (float) > 2.0, k(int) > 3.2 @@ -283,93 +283,94 @@ Status EsPredicate::build_disjuncts_list(const Expr* conjunct) { _disjuncts.push_back(predicate); return Status::OK(); } - - if (is_match_func(conjunct)) { - Expr* expr = conjunct->get_child(1); - ExtLiteral literal(expr->type().type, _context->get_value(expr, NULL)); - vector<ExtLiteral> query_conditions; - query_conditions.emplace_back(literal); - vector<ExtColumnDesc> cols; //TODO - ExtPredicate* predicate = new ExtFunction( - TExprNodeType::FUNCTION_CALL, - conjunct->fn().name.function_name, - cols, - query_conditions); - if (_es_query_status.ok()) { - _es_query_status - = BooleanQueryBuilder::check_es_query(*(ExtFunction *)predicate); - if (!_es_query_status.ok()) { - delete predicate; - return _es_query_status; - } - } - _disjuncts.push_back(predicate); - - return Status::OK(); - } - - if (TExprNodeType::FUNCTION_CALL == conjunct->node_type() - && (conjunct->fn().name.function_name == "is_null_pred" || conjunct->fn().name.function_name == "is_not_null_pred")) { - // such as sub-query: select * from (select split_part(k, "_", 1) as new_field from case_replay_for_milimin) t where t.new_field > 1; - // conjunct->get_child(0)->node_type() == TExprNodeType::FUNCTION_CALL, at present doris on es can not support push down function - RETURN_ERROR_IF_EXPR_IS_NOT_SLOTREF(conjunct->get_child(0)); - SlotRef* slot_ref = (SlotRef*)(conjunct->get_child(0)); - const SlotDescriptor* slot_desc = get_slot_desc(slot_ref); - bool is_not_null; - if (conjunct->fn().name.function_name == "is_null_pred") { - is_not_null = false; - } else { - is_not_null = true; - } - std::string col = slot_desc->col_name(); - if (_field_context.find(col) != _field_context.end()) { - col = _field_context[col]; - } - // use TExprNodeType::IS_NULL_PRED for BooleanQueryBuilder translate - ExtIsNullPredicate* predicate = new ExtIsNullPredicate(TExprNodeType::IS_NULL_PRED, col, slot_desc->type(), is_not_null); - _disjuncts.push_back(predicate); - return Status::OK(); - } - + // process function call predicate: esquery, is_null_pred, is_not_null_pred if (TExprNodeType::FUNCTION_CALL == conjunct->node_type()) { std::string fname = conjunct->fn().name.function_name; - if (fname != "like") { - return Status::InternalError("build disjuncts failed: function name is not like"); - } + if (fname == "esquery") { + if (conjunct->children().size() != 2) { + return Status::InternalError("build disjuncts failed: number of childs is not 2"); + } + Expr* expr = conjunct->get_child(1); + ExtLiteral literal(expr->type().type, _context->get_value(expr, NULL)); + vector<ExtLiteral> query_conditions; + query_conditions.emplace_back(literal); + vector<ExtColumnDesc> cols; + ExtPredicate* predicate = new ExtFunction( + TExprNodeType::FUNCTION_CALL, + "esquery", + cols, + query_conditions); + if (_es_query_status.ok()) { + _es_query_status = BooleanQueryBuilder::check_es_query(*(ExtFunction *)predicate); + if (!_es_query_status.ok()) { + delete predicate; + return _es_query_status; + } + } + _disjuncts.push_back(predicate); + } else if (fname == "is_null_pred" || fname == "is_not_null_pred") { + if (conjunct->children().size() != 1) { + return Status::InternalError("build disjuncts failed: number of childs is not 1"); + } + // such as sub-query: select * from (select split_part(k, "_", 1) as new_field from table) t where t.new_field > 1; + // conjunct->get_child(0)->node_type() == TExprNodeType::FUNCTION_CALL, at present doris on es can not support push down function + RETURN_ERROR_IF_EXPR_IS_NOT_SLOTREF(conjunct->get_child(0)); + SlotRef* slot_ref = (SlotRef*)(conjunct->get_child(0)); + const SlotDescriptor* slot_desc = get_slot_desc(slot_ref); + if (slot_desc == nullptr) { + return Status::InternalError("build disjuncts failed: no SLOT_REF child"); + } + bool is_not_null = fname == "is_not_null_pred" ? true : false; + std::string col = slot_desc->col_name(); + if (_field_context.find(col) != _field_context.end()) { + col = _field_context[col]; + } + // use TExprNodeType::IS_NULL_PRED for BooleanQueryBuilder translate + ExtIsNullPredicate* predicate = new ExtIsNullPredicate(TExprNodeType::IS_NULL_PRED, col, slot_desc->type(), is_not_null); + _disjuncts.push_back(predicate); + } else if (fname == "like") { + if (conjunct->children().size() != 2) { + return Status::InternalError("build disjuncts failed: number of childs is not 2"); + } + SlotRef* slot_ref = nullptr; + Expr* expr = nullptr; + if (TExprNodeType::SLOT_REF == conjunct->get_child(0)->node_type()) { + expr = conjunct->get_child(1); + slot_ref = (SlotRef*)(conjunct->get_child(0)); + } else if (TExprNodeType::SLOT_REF == conjunct->get_child(1)->node_type()) { + expr = conjunct->get_child(0); + slot_ref = (SlotRef*)(conjunct->get_child(1)); + } else { + return Status::InternalError("build disjuncts failed: no SLOT_REF child"); + } + const SlotDescriptor* slot_desc = get_slot_desc(slot_ref); + if (slot_desc == nullptr) { + return Status::InternalError("build disjuncts failed: slot_desc is null"); + } - SlotRef* slot_ref = nullptr; - Expr* expr = nullptr; - if (TExprNodeType::SLOT_REF == conjunct->get_child(0)->node_type()) { - expr = conjunct->get_child(1); - slot_ref = (SlotRef*)(conjunct->get_child(0)); - } else if (TExprNodeType::SLOT_REF == conjunct->get_child(1)->node_type()) { - expr = conjunct->get_child(0); - slot_ref = (SlotRef*)(conjunct->get_child(1)); + PrimitiveType type = expr->type().type; + if (type != TYPE_VARCHAR && type != TYPE_CHAR) { + return Status::InternalError("build disjuncts failed: like value is not a string"); + } + std::string col = slot_desc->col_name(); + if (_field_context.find(col) != _field_context.end()) { + col = _field_context[col]; + } + ExtLiteral literal(type, _context->get_value(expr, NULL)); + ExtPredicate* predicate = new ExtLikePredicate( + TExprNodeType::LIKE_PRED, + col, + slot_desc->type(), + literal); + + _disjuncts.push_back(predicate); } else { - return Status::InternalError("build disjuncts failed: no SLOT_REF child"); - } - - const SlotDescriptor* slot_desc = get_slot_desc(slot_ref); - if (slot_desc == nullptr) { - return Status::InternalError("build disjuncts failed: slot_desc is null"); - } - - PrimitiveType type = expr->type().type; - if (type != TYPE_VARCHAR && type != TYPE_CHAR) { - return Status::InternalError("build disjuncts failed: like value is not a string"); + std::stringstream ss; + ss << "can not process function predicate[ " + << fname + << " ]"; + return Status::InternalError(ss.str()); } - std::string col = slot_desc->col_name(); - if (_field_context.find(col) != _field_context.end()) { - col = _field_context[col]; - } - ExtLiteral literal(type, _context->get_value(expr, NULL)); - ExtPredicate* predicate = new ExtLikePredicate( - TExprNodeType::LIKE_PRED, - col, - slot_desc->type(), - literal); - - _disjuncts.push_back(predicate); return Status::OK(); } @@ -465,14 +466,6 @@ Status EsPredicate::build_disjuncts_list(const Expr* conjunct) { return Status::InternalError(ss.str()); } -bool EsPredicate::is_match_func(const Expr* conjunct) { - if (TExprNodeType::FUNCTION_CALL == conjunct->node_type() - && conjunct->fn().name.function_name == "esquery") { - return true; - } - return false; -} - const SlotDescriptor* EsPredicate::get_slot_desc(const SlotRef* slotRef) { const SlotDescriptor* slot_desc = nullptr; for (SlotDescriptor* slot : _tuple_desc->slots()) { diff --git a/be/src/exec/es/es_predicate.h b/be/src/exec/es/es_predicate.h index 5c0a72b..a3c6c4f 100644 --- a/be/src/exec/es/es_predicate.h +++ b/be/src/exec/es/es_predicate.h @@ -179,7 +179,7 @@ struct ExtFunction : public ExtPredicate { values(values) { } - const std::string& func_name; + const std::string func_name; std::vector<ExtColumnDesc> cols; const std::vector<ExtLiteral> values; }; @@ -205,7 +205,6 @@ public: private: Status build_disjuncts_list(const Expr* conjunct); - bool is_match_func(const Expr* conjunct); const SlotDescriptor* get_slot_desc(const SlotRef* slotRef); ExprContext* _context; --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org