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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]