From bbfae11ed7ae7a2cbf71eeec7ddba3095ed68e6f Mon Sep 17 00:00:00 2001 From: trueeyu Date: Mon, 10 Jul 2023 12:44:57 +0800 Subject: [PATCH] [BugFix] Fix the mem leak of build in predicate for es external table (#26631) (#26817) VExtLiteral is not deleted. ``` ==76869==ERROR: LeakSanitizer: detected memory leaks Direct leak of 40 byte(s) in 1 object(s) allocated from: #0 0x9793a37 in operator new(unsigned long) ../../.././libsanitizer/asan/asan_new_delete.cpp:99 #1 0x129dd44e in operator() /root/starrocks/be/src/exec/es/es_predicate.cpp:416 #2 0x129dd817 in build_inpred_values<(starrocks::LogicalType)5, starrocks::EsPredicate::_build_in_predicate(const starrocks::Expr*, bool*):: > /root/starrocks/be/src/exec/es/es_predicate.cpp:366 #3 0x129d7824 in starrocks::EsPredicate::_build_in_predicate(starrocks::Expr const*, bool*) /root/starrocks/be/src/exec/es/es_predicate.cpp:416 #4 0x129d2f2d in starrocks::EsPredicate::_vec_build_disjuncts_list(starrocks::Expr const*) /root/starrocks/be/src/exec/es/es_predicate.cpp:185 #5 0x129d2a53 in starrocks::EsPredicate::build_disjuncts_list() /root/starrocks/be/src/exec/es/es_predicate.cpp:148 #6 0x128ab50d in starrocks::connector::ESDataSource::_build_conjuncts() /root/starrocks/be/src/connector/es_connector.cpp:123 #7 0x128aa7c5 in starrocks::connector::ESDataSource::open(starrocks::RuntimeState*) /root/starrocks/be/src/connector/es_connector.cpp:89 #8 0x9e33847 in starrocks::pipeline::ConnectorChunkSource::_open_data_source(starrocks::RuntimeState*) /root/starrocks/be/src/exec/pipeline/scan/connector_scan_operator.cpp:504 #9 0x9e33ed0 in starrocks::pipeline::ConnectorChunkSource::_read_chunk(starrocks::RuntimeState*, std::shared_ptr*) /root/starrocks/be/src/exec/pipeline/scan/connector_scan_operator.cpp:533 #10 0xabc8b65 in starrocks::pipeline::ChunkSource::buffer_next_batch_chunks_blocking(starrocks::RuntimeState*, unsigned long, starrocks::workgroup::WorkGroup const*) /root/starrocks/be/src/exec/pipeline/scan/chunk_source.cpp:67 #11 0x9e168c7 in operator() /root/starrocks/be/src/exec/pipeline/scan/scan_operator.cpp:396 #12 0x9e1c157 in __invoke_impl&> /opt/gcc/usr/include/c++/10.3.0/bits/invoke.h:60 #13 0x9e1c005 in __invoke_r&> /opt/gcc/usr/include/c++/10.3.0/bits/invoke.h:110 #14 0x9e1be7a in _M_invoke /opt/gcc/usr/include/c++/10.3.0/bits/std_function.h:291 #15 0x992a271 in std::function::operator()() const /opt/gcc/usr/include/c++/10.3.0/bits/std_function.h:622 #16 0x9e519fa in starrocks::workgroup::ScanExecutor::worker_thread() /root/starrocks/be/src/exec/workgroup/scan_executor.cpp:67 #17 0x9e5121f in operator() /root/starrocks/be/src/exec/workgroup/scan_executor.cpp:31 #18 0x9e52c5d in __invoke_impl&> /opt/gcc/usr/include/c++/10.3.0/bits/invoke.h:60 #19 0x9e52925 in __invoke_r&> /opt/gcc/usr/include/c++/10.3.0/bits/invoke.h:110 #20 0x9e5249a in _M_invoke /opt/gcc/usr/include/c++/10.3.0/bits/std_function.h:291 #21 0x992a271 in std::function::operator()() const /opt/gcc/usr/include/c++/10.3.0/bits/std_function.h:622 #22 0x1181f23d in starrocks::FunctionRunnable::run() /root/starrocks/be/src/util/threadpool.cpp:58 #23 0x1181bff2 in starrocks::ThreadPool::dispatch_thread() /root/starrocks/be/src/util/threadpool.cpp:553 #24 0x11837c4b in void std::__invoke_impl(std::__invoke_memfun_deref, void (starrocks::ThreadPool::*&)(), starrocks::ThreadPool*&) /opt/gcc/usr/include/c++/10.3.0/bits/invoke.h:73 #25 0x118375a4 in std::__invoke_result::type std::__invoke(void (starrocks::ThreadPool::*&)(), starrocks::ThreadPool*&) /opt/gcc/usr/include/c++/10. 3.0/bits/invoke.h:95 #26 0x1183699b in void std::_Bind::__call(std::tuple<>&&, std::_Index_tuple<0ul>) /opt/gcc/usr/include/c++/10.3.0/functional:416 #27 0x118352fd in void std::_Bind::operator()<, void>() /opt/gcc/usr/include/c++/10.3.0/functional:499 #28 0x11832361 in void std::__invoke_impl&>(std::__invoke_other, std::_Bind&) /opt/gcc/usr/include/c++/10.3.0/bits/invoke.h:60 #29 0x1182fcc5 in std::enable_if&>, void>::type std::__invoke_r&>(std::_Bind&) /opt/gcc/usr/include/c++/10.3.0/bits/invoke.h:110 ``` Signed-off-by: trueeyu --- be/src/exec/es/es_predicate.cpp | 49 ++++++++++++++++----------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/be/src/exec/es/es_predicate.cpp b/be/src/exec/es/es_predicate.cpp index bbc03ee2f3038..1f3109f46bebd 100644 --- a/be/src/exec/es/es_predicate.cpp +++ b/be/src/exec/es/es_predicate.cpp @@ -223,7 +223,7 @@ Status EsPredicate::_build_functioncall_predicate(const Expr* conjunct, bool* ha return Status::InternalError("build disjuncts failed: number of childs is not 2"); } Expr* expr = conjunct->get_child(1); - ASSIGN_OR_RETURN(auto expr_value, _context->evaluate(expr, nullptr)); + ASSIGN_OR_RETURN(auto expr_value, _context->evaluate(expr, nullptr)) auto literal = _pool->add(new VExtLiteral(expr->type().type, std::move(expr_value), _timezone)); std::vector query_conditions; query_conditions.emplace_back(literal); @@ -245,7 +245,7 @@ Status EsPredicate::_build_functioncall_predicate(const Expr* conjunct, bool* ha // 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)); - ColumnRef* column_ref = const_cast( + auto* column_ref = const_cast( down_cast(Expr::expr_without_cast(conjunct->get_child(0)))); const SlotDescriptor* slot_desc = get_slot_desc(column_ref->slot_id()); @@ -253,14 +253,13 @@ Status EsPredicate::_build_functioncall_predicate(const Expr* conjunct, bool* ha 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; + bool is_not_null = fname == "is_not_null_pred"; 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); + auto* 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) { @@ -322,13 +321,13 @@ Status build_inpred_values(const Predicate* pred, bool& is_not_in, Func&& func) return Status::OK(); } -#define BUILD_INPRED_VALUES(TYPE) \ - case TYPE: { \ - RETURN_IF_ERROR(build_inpred_values(pred, is_not_in, [&](auto& v) { \ - in_pred_values.emplace_back(new VExtLiteral( \ - slot_desc->type().type, vectorized::ColumnHelper::create_const_column(v, 1), _timezone)); \ - })); \ - break; \ +#define BUILD_INPRED_VALUES(TYPE) \ + case TYPE: { \ + RETURN_IF_ERROR(build_inpred_values(pred, is_not_in, [&](auto& v) { \ + in_pred_values.emplace_back(_pool->add(new VExtLiteral( \ + slot_desc->type().type, vectorized::ColumnHelper::create_const_column(v, 1), _timezone))); \ + })); \ + break; \ } Status EsPredicate::_build_in_predicate(const Expr* conjunct, bool* handled) { @@ -345,7 +344,7 @@ Status EsPredicate::_build_in_predicate(const Expr* conjunct, bool* handled) { } std::vector in_pred_values; - const Predicate* pred = static_cast(conjunct); + const auto* pred = static_cast(conjunct); const Expr* expr = Expr::expr_without_cast(pred->get_child(0)); if (expr->node_type() != TExprNodeType::SLOT_REF) { @@ -366,18 +365,18 @@ Status EsPredicate::_build_in_predicate(const Expr* conjunct, bool* handled) { bool is_not_in = false; // insert in list to ExtLiteral switch (expr->type().type) { - BUILD_INPRED_VALUES(TYPE_BOOLEAN); - BUILD_INPRED_VALUES(TYPE_INT); - BUILD_INPRED_VALUES(TYPE_TINYINT); - BUILD_INPRED_VALUES(TYPE_SMALLINT); - BUILD_INPRED_VALUES(TYPE_BIGINT); - BUILD_INPRED_VALUES(TYPE_LARGEINT); - BUILD_INPRED_VALUES(TYPE_FLOAT); - BUILD_INPRED_VALUES(TYPE_DOUBLE); - BUILD_INPRED_VALUES(TYPE_DATE); - BUILD_INPRED_VALUES(TYPE_DATETIME); - BUILD_INPRED_VALUES(TYPE_CHAR); - BUILD_INPRED_VALUES(TYPE_VARCHAR); + BUILD_INPRED_VALUES(TYPE_BOOLEAN) + BUILD_INPRED_VALUES(TYPE_INT) + BUILD_INPRED_VALUES(TYPE_TINYINT) + BUILD_INPRED_VALUES(TYPE_SMALLINT) + BUILD_INPRED_VALUES(TYPE_BIGINT) + BUILD_INPRED_VALUES(TYPE_LARGEINT) + BUILD_INPRED_VALUES(TYPE_FLOAT) + BUILD_INPRED_VALUES(TYPE_DOUBLE) + BUILD_INPRED_VALUES(TYPE_DATE) + BUILD_INPRED_VALUES(TYPE_DATETIME) + BUILD_INPRED_VALUES(TYPE_CHAR) + BUILD_INPRED_VALUES(TYPE_VARCHAR) default: DCHECK(false) << "unsupported type:" << expr->type().type; return Status::InternalError("unsupported type to push down to ES");