diff --git a/src/pl/ob_pl_code_generator.cpp b/src/pl/ob_pl_code_generator.cpp index 4b96c958db..a855ab59e0 100644 --- a/src/pl/ob_pl_code_generator.cpp +++ b/src/pl/ob_pl_code_generator.cpp @@ -7818,6 +7818,24 @@ int ObPLCodeGenerator::generate_goto_label(const ObPLStmt &stmt) return ret; } +int ObPLCodeGenerator::generate_destruct_obj(const ObPLStmt &s, ObLLVMValue &src_datum) +{ + int ret = OB_SUCCESS; + ObSEArray args; + + OZ (args.push_back(get_vars()[CTX_IDX])); + OZ (args.push_back(src_datum)); + if (OB_SUCC(ret)) { + jit::ObLLVMValue ret_err; + if (OB_FAIL(get_helper().create_call(ObString("spi_destruct_obj"), get_spi_service().spi_destruct_obj_, args, ret_err))) { + LOG_WARN("failed to create call", K(ret)); + } else if (OB_FAIL(check_success(ret_err, s.get_stmt_id(), s.get_block()->in_notfound(), s.get_block()->in_warning()))) { + LOG_WARN("failed to check success", K(ret)); + } else { /*do nothing*/ } + } + return ret; +} + int ObPLCodeGenerator::generate_out_param( const ObPLStmt &s, const ObIArray ¶m_desc, ObLLVMValue ¶ms, int64_t i) { @@ -7868,26 +7886,18 @@ int ObPLCodeGenerator::generate_out_param( s.get_block()->in_notfound(), s.get_block()->in_warning(), OB_INVALID_ID)); - if (OB_SUCC(ret) && PL_CALL == s.get_type()) { + if (OB_FAIL(ret)) { + } else if (PL_CALL == s.get_type()) { const ObPLCallStmt *call_stmt = static_cast(&s); if (call_stmt->get_nocopy_params().count() > i && OB_INVALID_INDEX != call_stmt->get_nocopy_params().at(i) && !param_desc.at(i).is_pure_out()) { // inner call nocopy的inout参数传递是指针, 无需释放 } else { - ObSEArray args; - - OZ (args.push_back(get_vars()[CTX_IDX])); - OZ (args.push_back(src_datum)); - if (OB_SUCC(ret)) { - jit::ObLLVMValue ret_err; - if (OB_FAIL(get_helper().create_call(ObString("spi_destruct_obj"), get_spi_service().spi_destruct_obj_, args, ret_err))) { - LOG_WARN("failed to create call", K(ret)); - } else if (OB_FAIL(check_success(ret_err, s.get_stmt_id(), s.get_block()->in_notfound(), s.get_block()->in_warning()))) { - LOG_WARN("failed to check success", K(ret)); - } else { /*do nothing*/ } - } + OZ (generate_destruct_obj(s, src_datum)); } + } else if (PL_EXECUTE == s.get_type() && param_desc.at(i).is_pure_out()) { + OZ (generate_destruct_obj(s, src_datum)); } } } else { //处理基础类型的出参 diff --git a/src/pl/ob_pl_code_generator.h b/src/pl/ob_pl_code_generator.h index f859713493..ceae8e7599 100644 --- a/src/pl/ob_pl_code_generator.h +++ b/src/pl/ob_pl_code_generator.h @@ -338,6 +338,7 @@ public: const ObSqlExpression *get_expr(int64_t i) const { return i < 0 || i >= exprs_.count() ? NULL : exprs_.at(i); } ObSqlExpression *get_expr(int64_t i) { return i < 0 || i >= exprs_.count() ? NULL : exprs_.at(i); } int generate_goto_label(const ObPLStmt &stmt); + int generate_destruct_obj(const ObPLStmt &s, jit::ObLLVMValue &src_datum); int generate_out_param( const ObPLStmt &s, const ObIArray ¶m_desc, diff --git a/src/pl/ob_pl_resolver.cpp b/src/pl/ob_pl_resolver.cpp index 60a5be6274..954afcf66b 100644 --- a/src/pl/ob_pl_resolver.cpp +++ b/src/pl/ob_pl_resolver.cpp @@ -751,10 +751,16 @@ int ObPLResolver::resolve(const ObStmtNodeTree *parse_tree, ObPLFunctionAST &fun } } } - - if (OB_SUCC(ret) && NULL != current_block_ && NULL != stmt) { + if (OB_FAIL(ret)) { + if (NULL != stmt) { + stmt->~ObPLStmt(); + } + } else if (NULL != current_block_ && NULL != stmt) { if (OB_FAIL(current_block_->add_stmt(stmt))) { LOG_WARN("failed to add stmt", K(stmt), K(ret)); + if (NULL != stmt) { + stmt->~ObPLStmt(); + } } } } diff --git a/src/pl/ob_pl_type.cpp b/src/pl/ob_pl_type.cpp index 7a3f278404..8c44b940de 100644 --- a/src/pl/ob_pl_type.cpp +++ b/src/pl/ob_pl_type.cpp @@ -1797,6 +1797,7 @@ int ObPLCursorInfo::close(sql::ObSQLSessionInfo &session, bool is_reuse) LOG_WARN("close mysql result set failed", K(ret), K(close_ret)); } ret = (OB_SUCCESS == ret ? close_ret : ret); + spi_result->destruct_exec_params(session); //spi_result->get_mysql_result().reset(); int reset_ret = spi_result->reset_cursor_env(session); ret = (OB_SUCCESS == ret ? reset_ret : ret); diff --git a/src/pl/ob_pl_user_type.cpp b/src/pl/ob_pl_user_type.cpp index 746f65491a..6ab9f9dc4f 100644 --- a/src/pl/ob_pl_user_type.cpp +++ b/src/pl/ob_pl_user_type.cpp @@ -1779,7 +1779,8 @@ int ObPLCollection::deep_copy(ObPLCollection *src, ObIAllocator *allocator) } CK (OB_NOT_NULL(new_objs = reinterpret_cast(data))); CK (OB_NOT_NULL(old_objs = reinterpret_cast(src->get_data()))); - for (int64_t i = 0; OB_SUCC(ret) && i < src->get_count(); ++i) { + int64_t i = 0; + for (; OB_SUCC(ret) && i < src->get_count(); ++i) { ObObj old_obj = old_objs[i]; new (&new_objs[i])ObObj(); if (old_objs[i].is_invalid_type() && src->is_of_composite()) { @@ -1791,6 +1792,18 @@ int ObPLCollection::deep_copy(ObPLCollection *src, ObIAllocator *allocator) new_objs[i].set_type(ObMaxType); } } + // 对于已经copy成功的new obj释放内存 + if (OB_FAIL(ret) && OB_NOT_NULL(data)) { + for (int64_t j = 0; j <= i; ++j) { + int tmp = ObUserDefinedType::destruct_obj(new_objs[j]); + if (OB_SUCCESS != tmp) { + LOG_WARN("fail torelease memory", K(ret), K(tmp)); + } + } + if (NULL == allocator) { + coll_allocator->reset(); + } + } } if (OB_SUCC(ret)) { set_allocator(coll_allocator);