From 4d6995673a22fe1681dff5a18f3af03a7eb8eb99 Mon Sep 17 00:00:00 2001 From: obdev Date: Wed, 28 Dec 2022 03:08:07 +0000 Subject: [PATCH] [CP] [to #46708308] add ObPLCtxGuard for udf calc --- src/pl/ob_pl.h | 25 +++++++++++++++++++++++++ src/sql/engine/expr/ob_expr_udf.cpp | 6 ++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/pl/ob_pl.h b/src/pl/ob_pl.h index 28922c461..131091091 100644 --- a/src/pl/ob_pl.h +++ b/src/pl/ob_pl.h @@ -614,6 +614,9 @@ public: int add(ObObj &obj) { return objects_.push_back(obj); } + void clear() { + objects_.reset(); + } void reset_obj(); common::ObIArray& get_objects() { return objects_; } private: @@ -624,6 +627,28 @@ private: ObSEArray objects_; }; +class ObPLCtxGuard +{ +public: + ObPLCtxGuard(ObPLCtx *ctx, int& ret) : ctx_(ctx), ret_(ret) { + if (OB_NOT_NULL(ctx)) { + ret_ = objects_.assign(ctx->get_objects()); + ctx_->clear(); + } + } + + ~ObPLCtxGuard() { + if (OB_SUCCESS == ret_ && OB_NOT_NULL(ctx_)) { + ret_ = ctx_->get_objects().assign(objects_); + } + } + +private: + ObPLCtx *ctx_; + int &ret_; + ObSEArray objects_; +}; + class ObPLPackageGuard; diff --git a/src/sql/engine/expr/ob_expr_udf.cpp b/src/sql/engine/expr/ob_expr_udf.cpp index 1bc6ca611..024534544 100644 --- a/src/sql/engine/expr/ob_expr_udf.cpp +++ b/src/sql/engine/expr/ob_expr_udf.cpp @@ -480,7 +480,7 @@ int ObExprUDF::eval_udf(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res) CK (0 < udf_params->count()); OZ (ns.init_complex_obj(alloc, pl_type, udf_params->at(0), false, false)); } - + pl::ObPLCtxGuard guard(ctx.exec_ctx_.get_pl_ctx(), ret); ObArenaAllocator allocator; try { int64_t package_id = info->is_udt_udf_ ? @@ -512,7 +512,9 @@ int ObExprUDF::eval_udf(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res) } if (OB_FAIL(ret)) { } else if (info->is_called_in_sql_) { - if (tmp_result.is_pl_extend()) { + // memory of ref cursor on session, do not copy it. + if (tmp_result.is_pl_extend() + && tmp_result.get_meta().get_extend_type() != pl::PL_REF_CURSOR_TYPE) { OZ (pl::ObUserDefinedType::deep_copy_obj(alloc, tmp_result, result, true)); OZ (pl::ObUserDefinedType::destruct_obj(tmp_result, ctx.exec_ctx_.get_my_session())); CK (OB_NOT_NULL(ctx.exec_ctx_.get_pl_ctx()));