From bddcfc3d68be946cdb5f0444199d70bd98f0197b Mon Sep 17 00:00:00 2001 From: hanr881 <1741282579@qq.com> Date: Fri, 12 May 2023 06:41:11 +0000 Subject: [PATCH] to issue<49576316>:fix core when package complex variable as udf out param --- src/sql/engine/expr/ob_expr_udf.cpp | 16 ++++++++-- src/sql/resolver/expr/ob_raw_expr_util.cpp | 36 +++++++++++++--------- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/sql/engine/expr/ob_expr_udf.cpp b/src/sql/engine/expr/ob_expr_udf.cpp index b301d46f4..5f22413d6 100644 --- a/src/sql/engine/expr/ob_expr_udf.cpp +++ b/src/sql/engine/expr/ob_expr_udf.cpp @@ -355,8 +355,20 @@ int ObExprUDF::process_out_params(const ObObj *objs_stack, result)); OX (result.copy_value_or_obj(*obj, true)); OX (result.set_param_meta()); - } else { - // do nothing ... + } else if (params_desc.at(i).is_obj_access_out() && + OB_INVALID_ID != params_desc.at(i).get_package_id() && + OB_INVALID_ID != params_desc.at(i).get_index()) { + ObIAllocator *pkg_allocator = NULL; + pl::ObPLExecCtx plctx(nullptr, &exec_ctx, nullptr,nullptr,nullptr,nullptr); + ObObj &obj = iparams.at(i); + OZ (ObSPIService::spi_get_package_allocator(&plctx, params_desc.at(i).get_package_id(), pkg_allocator)); + if (OB_SUCC(ret) && nullptr != pkg_allocator) { + if (obj.is_ext() && obj.get_meta().get_extend_type() != pl::PL_REF_CURSOR_TYPE) { + OZ (pl::ObUserDefinedType::deep_copy_obj(*pkg_allocator, obj, obj, true)); + } else { + OZ (deep_copy_obj(*pkg_allocator, obj, obj)); + } + } } } return ret; diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index c806e4e4f..c59ffc721 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -1049,6 +1049,17 @@ int ObRawExprUtils::resolve_udf_param_exprs(ObResolverParams ¶ms, } } } +#define GET_CONST_EXPR_VALUE(expr, val) \ +do { \ + const ObConstRawExpr *c_expr = static_cast(expr); \ + CK (OB_NOT_NULL(c_expr)); \ + CK (c_expr->get_value().is_uint64() \ + || c_expr->get_value().is_int() \ + || c_expr->get_value().is_unknown()); \ + OX (val = c_expr->get_value().is_uint64() ? c_expr->get_value().get_uint64() \ + : c_expr->get_value().is_int() ? c_expr->get_value().get_int() \ + : c_expr->get_value().get_unknown()); \ +} while (0) if (OB_FAIL(ret)) { } else if(T_NULL == iexpr->get_expr_type() && 0 == i && udf_info.is_udf_udt_cons()) { // do nothing, udt constructor first param is mocked with null expr @@ -1066,11 +1077,21 @@ int ObRawExprUtils::resolve_udf_param_exprs(ObResolverParams ¶ms, K(iexpr->get_expr_type()), K(ret)); } else if (T_OBJ_ACCESS_REF == iexpr->get_expr_type()) { ObObjAccessRawExpr* obj = static_cast(iexpr); + uint64_t pkg_id = OB_INVALID_ID; + uint64_t var_id = OB_INVALID_ID; CK (OB_NOT_NULL(obj)); OX (obj->set_write(true)); OZ (obj->formalize(params.session_info_)); + if (obj->get_access_idxs().count() > 0 && + OB_NOT_NULL(obj->get_access_idxs().at(0).get_sysfunc_) && + T_OP_GET_PACKAGE_VAR == obj->get_access_idxs().at(0).get_sysfunc_->get_expr_type()) { + const ObSysFunRawExpr *f_expr = static_cast(obj->get_access_idxs().at(0).get_sysfunc_); + CK (OB_NOT_NULL(f_expr) && f_expr->get_param_count() >= 2); + GET_CONST_EXPR_VALUE(f_expr->get_param_expr(0), pkg_id); + GET_CONST_EXPR_VALUE(f_expr->get_param_expr(1), var_id); + } OZ (udf_raw_expr->add_param_desc( - ObUDFParamDesc(ObUDFParamDesc::OBJ_ACCESS_OUT))); + ObUDFParamDesc(ObUDFParamDesc::OBJ_ACCESS_OUT, var_id, OB_INVALID_ID, pkg_id))); } else if (T_QUESTIONMARK == iexpr->get_expr_type()) { ObConstRawExpr *c_expr = static_cast(iexpr); CK (OB_NOT_NULL(c_expr)); @@ -1078,19 +1099,6 @@ int ObRawExprUtils::resolve_udf_param_exprs(ObResolverParams ¶ms, OZ (udf_raw_expr->add_param_desc( ObUDFParamDesc(ObUDFParamDesc::LOCAL_OUT, c_expr->get_value().get_unknown()))); } else if (T_OP_GET_PACKAGE_VAR == iexpr->get_expr_type()) { - -#define GET_CONST_EXPR_VALUE(expr, val) \ -do { \ - const ObConstRawExpr *c_expr = static_cast(expr); \ - CK (OB_NOT_NULL(c_expr)); \ - CK (c_expr->get_value().is_uint64() \ - || c_expr->get_value().is_int() \ - || c_expr->get_value().is_unknown()); \ - OX (val = c_expr->get_value().is_uint64() ? c_expr->get_value().get_uint64() \ - : c_expr->get_value().is_int() ? c_expr->get_value().get_int() \ - : c_expr->get_value().get_unknown()); \ -} while (0) - const ObSysFunRawExpr *f_expr = static_cast(iexpr); uint64_t pkg_id = OB_INVALID_ID; uint64_t var_id = OB_INVALID_ID;