From fb4195d21aff0485b9e1817c2b922c8bcce7fca1 Mon Sep 17 00:00:00 2001 From: hanr881 <1741282579@qq.com> Date: Mon, 8 Apr 2024 09:53:38 +0000 Subject: [PATCH] [CP] to issue<55645636>:fix two cursor memory leak stack --- src/pl/ob_pl_type.cpp | 9 ++++-- src/pl/ob_pl_type.h | 3 +- src/pl/sys_package/ob_dbms_sql.cpp | 4 ++- src/sql/engine/expr/ob_expr_subquery_ref.cpp | 4 ++- src/sql/ob_spi.cpp | 29 ++++++++++++++++---- src/sql/ob_spi.h | 8 ++++-- 6 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/pl/ob_pl_type.cpp b/src/pl/ob_pl_type.cpp index 0d8fb78a3b..067bfb1853 100644 --- a/src/pl/ob_pl_type.cpp +++ b/src/pl/ob_pl_type.cpp @@ -2087,7 +2087,9 @@ int ObPLCursorInfo::deep_copy(ObPLCursorInfo &src, common::ObIAllocator *allocat // it will happend not in ps cursor. OZ (prepare_spi_cursor(dest_cursor, src_cursor->row_store_.get_tenant_id(), - src_cursor->row_store_.get_mem_limit())); + src_cursor->row_store_.get_mem_limit(), + false, + src_cursor->session_info_)); CK (OB_NOT_NULL(dest_cursor)); OZ (dest_cursor->row_desc_.assign(src_cursor->row_desc_)); #ifdef OB_BUILD_ORACLE_PL @@ -2375,7 +2377,8 @@ int ObPLCursorInfo::prepare_spi_result(ObPLExecCtx *ctx, ObSPIResultSet *&spi_re int ObPLCursorInfo::prepare_spi_cursor(ObSPICursor *&spi_cursor, uint64_t tenant_id, uint64_t mem_limit, - bool is_local_for_update) + bool is_local_for_update, + sql::ObSQLSessionInfo* session_info) { int ret = OB_SUCCESS; ObIAllocator *spi_allocator = get_allocator(); @@ -2389,7 +2392,7 @@ int ObPLCursorInfo::prepare_spi_cursor(ObSPICursor *&spi_cursor, OX (spi_cursor_ = spi_allocator->alloc(alloc_size)); OV (OB_NOT_NULL(spi_cursor_), OB_ALLOCATE_MEMORY_FAILED); } - OX (spi_cursor = new (spi_cursor_) ObSPICursor(*spi_allocator)); + OX (spi_cursor = new (spi_cursor_) ObSPICursor(*spi_allocator, session_info)); OX (last_stream_cursor_ = false); if (OB_SUCC(ret)) { if (OB_INVALID_SIZE == mem_limit) { diff --git a/src/pl/ob_pl_type.h b/src/pl/ob_pl_type.h index f28b278c5c..94b566735a 100644 --- a/src/pl/ob_pl_type.h +++ b/src/pl/ob_pl_type.h @@ -1028,7 +1028,8 @@ public: int prepare_spi_cursor(sql::ObSPICursor *&spi_cursor, uint64_t tenant_id, uint64_t mem_limit, - bool is_local_for_update = false); + bool is_local_for_update = false, + sql::ObSQLSessionInfo* session_info = nullptr); ObCurTraceId::TraceId *get_sql_trace_id() { return &sql_trace_id_; } diff --git a/src/pl/sys_package/ob_dbms_sql.cpp b/src/pl/sys_package/ob_dbms_sql.cpp index 57ecd4de25..ac77292cdb 100644 --- a/src/pl/sys_package/ob_dbms_sql.cpp +++ b/src/pl/sys_package/ob_dbms_sql.cpp @@ -1619,7 +1619,9 @@ int ObPLDbmsSql::fill_dbms_cursor(ObSQLSessionInfo *session, OZ (session->get_tmp_table_size(size)); OZ (new_cursor->prepare_spi_cursor(spi_cursor, session->get_effective_tenant_id(), - size)); + size, + false, + session)); OV (OB_NOT_NULL(spi_cursor)); if OB_FAIL(ret) { diff --git a/src/sql/engine/expr/ob_expr_subquery_ref.cpp b/src/sql/engine/expr/ob_expr_subquery_ref.cpp index 81193f18f2..c7883e788d 100644 --- a/src/sql/engine/expr/ob_expr_subquery_ref.cpp +++ b/src/sql/engine/expr/ob_expr_subquery_ref.cpp @@ -347,7 +347,9 @@ int ObExprSubQueryRef::expr_eval( OZ (session->get_tmp_table_size(size)); OZ (cursor->prepare_spi_cursor(spi_cursor, session->get_effective_tenant_id(), - size)); + size, + false, + session)); OZ (spi_cursor->row_desc_.assign(extra_info->row_desc_)); while (OB_SUCC(ret)) { if (OB_FAIL(iter->get_next_row())) { diff --git a/src/sql/ob_spi.cpp b/src/sql/ob_spi.cpp index 0ca53e31f1..7bf63048fe 100644 --- a/src/sql/ob_spi.cpp +++ b/src/sql/ob_spi.cpp @@ -936,9 +936,15 @@ int ObSPIService::spi_calc_expr(ObPLExecCtx *ctx, if (has_lob_header) { result->ObObj::set_has_lob_header(); } - param = *result; - param.set_is_ref_cursor_type(is_ref_cursor); - param.set_param_meta(); + if (is_ref_cursor && + param.get_ext() != 0 && result->is_null()) { + OZ (spi_add_ref_cursor_refcount(ctx, ¶m, -1)); + } + if (OB_SUCC(ret)) { + param = *result; + param.set_is_ref_cursor_type(is_ref_cursor); + param.set_param_meta(); + } } else if (!is_ref_cursor) { int64_t orig_udt_id = ctx->params_->at(result_idx).get_udt_id(); ctx->params_->at(result_idx) = *result; @@ -3790,7 +3796,8 @@ int ObSPIService::spi_cursor_open(ObPLExecCtx *ctx, OZ (cursor->prepare_spi_cursor(spi_cursor, session_info->get_effective_tenant_id(), size, - for_update && !is_server_cursor), K(size)); + for_update && !is_server_cursor, + session_info), K(size)); //if (is_server_cursor) { // not only server cursor need field set // normal cursor maybe convert to session cursor by to_cursor_number @@ -4106,7 +4113,9 @@ int ObSPIService::dbms_cursor_open(ObPLExecCtx *ctx, retry_ctrl.clear_state_before_each_retry(session->get_retry_info_for_update()); OZ (cursor.prepare_spi_cursor(spi_cursor, session->get_effective_tenant_id(), - size)); + size, + false, + session)); OZ (GCTX.schema_service_->get_tenant_schema_guard(session->get_effective_tenant_id(), spi_result.get_scheme_guard())); OZ (spi_result.get_scheme_guard().get_schema_version(session->get_effective_tenant_id(), tenant_version)); OZ (spi_result.get_scheme_guard().get_schema_version(OB_SYS_TENANT_ID, sys_version)); @@ -6189,7 +6198,12 @@ int ObSPIService::spi_copy_datum(ObPLExecCtx *ctx, if (OB_FAIL(ret)) { } else if (src->is_null() || ObMaxType == src->get_type()) { //ObMaxTC means deleted element in Collection, no need to copy - *dest = *src; + uint8 type = dest->get_meta().get_extend_type(); + if ((PL_CURSOR_TYPE == type || PL_REF_CURSOR_TYPE == type) && dest->get_ext() != 0) { + OZ (spi_add_ref_cursor_refcount(ctx, dest, -1)); + } else { + *dest = *src; + } } else if (PL_CURSOR_TYPE == src->get_meta().get_extend_type() || PL_REF_CURSOR_TYPE == src->get_meta().get_extend_type()) { OZ (spi_copy_ref_cursor(ctx, allocator, src, dest, dest_type, package_id)); @@ -7925,7 +7939,10 @@ int ObSPIService::store_result(ObPLExecCtx *ctx, } else { OZ (deep_copy_obj(*cast_ctx.allocator_v2_, calc_array->at(0), result)); } + bool is_ref_cursor = false; + OX (is_ref_cursor = params->at(param_idx).is_ref_cursor_type()); OX (params->at(param_idx) = result); + OX (params->at(param_idx).set_is_ref_cursor_type(is_ref_cursor)); OX (params->at(param_idx).set_param_meta()); OZ (spi_process_nocopy_params(ctx, param_idx)); OX (accuracy.set_accuracy(result_types[0].accuracy_)); diff --git a/src/sql/ob_spi.h b/src/sql/ob_spi.h index 915a19b26c..608a2f7565 100644 --- a/src/sql/ob_spi.h +++ b/src/sql/ob_spi.h @@ -43,8 +43,9 @@ class ObExprObjAccess; struct ObSPICursor { - ObSPICursor(ObIAllocator &allocator) : - row_store_(), row_desc_(), allocator_(&allocator), cur_(0), fields_(allocator), complex_objs_() + ObSPICursor(ObIAllocator &allocator, sql::ObSQLSessionInfo* session_info) : + row_store_(), row_desc_(), allocator_(&allocator), cur_(0), fields_(allocator), complex_objs_(), + session_info_(session_info) { row_desc_.set_tenant_id(MTL_ID()); complex_objs_.reset(); @@ -54,7 +55,7 @@ struct ObSPICursor ~ObSPICursor() { for (int64_t i = 0; i < complex_objs_.count(); ++i) { - (void)(pl::ObUserDefinedType::destruct_obj(complex_objs_.at(i))); + (void)(pl::ObUserDefinedType::destruct_obj(complex_objs_.at(i), session_info_)); } } @@ -64,6 +65,7 @@ struct ObSPICursor int64_t cur_; common::ColumnsFieldArray fields_; ObArray complex_objs_; + sql::ObSQLSessionInfo* session_info_; }; struct ObSPIOutParams