diff --git a/src/pl/ob_pl.cpp b/src/pl/ob_pl.cpp index 131e135b9c..9a1d962444 100644 --- a/src/pl/ob_pl.cpp +++ b/src/pl/ob_pl.cpp @@ -2163,10 +2163,36 @@ int ObPLExecState::set_var(int64_t var_idx, const ObObjParam& value) { int ret = OB_SUCCESS; ParamStore *params = ctx_.params_; + ObObjParam copy_value; + CK (OB_NOT_NULL(params)); CK (OB_NOT_NULL(get_allocator())); CK (var_idx >= 0 && var_idx < params->count()); - OZ (deep_copy_obj(*get_allocator(), value, params->at(var_idx))); + + if (OB_SUCC(ret) && params->at(var_idx).is_pl_extend() && params->at(var_idx).get_ext() != 0) { + OZ (ObUserDefinedType::destruct_obj(params->at(var_idx), ctx_.exec_ctx_->get_my_session())); + } + + if (OB_FAIL(ret)) { + } else if (value.is_pl_extend() && value.get_ext() != 0) { + OZ (ObUserDefinedType::deep_copy_obj(*get_allocator(), value, copy_value)); + } else { + OZ (deep_copy_obj(*get_allocator(), value, copy_value)); + } + + if (OB_FAIL(ret)) { + } else if (!copy_value.is_ext()) { + bool is_ref_cursor = params->at(var_idx).is_ref_cursor_type(); + copy_value.ObObj::set_scale(params->at(var_idx).get_meta().get_scale()); + copy_value.set_accuracy(params->at(var_idx).get_accuracy()); + params->at(var_idx) = copy_value; + params->at(var_idx).set_is_ref_cursor_type(is_ref_cursor); + params->at(var_idx).set_param_meta(); + } else if (!params->at(var_idx).is_ref_cursor_type()) { + int64_t udt_id = params->at(var_idx).get_udt_id(); + params->at(var_idx) = copy_value; + params->at(var_idx).set_udt_id(udt_id); + } OX (params->at(var_idx).set_param_meta()); return ret; } diff --git a/src/pl/ob_pl_package_state.cpp b/src/pl/ob_pl_package_state.cpp index 64bfac86d0..736ee4558f 100644 --- a/src/pl/ob_pl_package_state.cpp +++ b/src/pl/ob_pl_package_state.cpp @@ -333,7 +333,8 @@ int ObPLPackageState::convert_changed_info_to_string_kvs(ObPLExecCtx &pl_ctx, Ob OZ (pl_ctx.exec_ctx_->get_sql_ctx()->schema_guard_->get_package_info(tenant_id, package_id_, package_info)); if (OB_NOT_NULL(package_info)) { for (int64_t i = 0; i < vars_.count() && OB_SUCCESS == ret; ++i) { - if (changed_vars_.has_member(i)) { + if (changed_vars_.has_member(i) + && vars_.at(i).get_meta().get_extend_type() != PL_REF_CURSOR_TYPE) { key_str.reset(); value_obj.reset(); if (OB_FAIL(convert_info_to_string_kv(pl_ctx, i, VARIABLE, key_str, value_obj))) { diff --git a/src/pl/ob_pl_type.h b/src/pl/ob_pl_type.h index de6479ccfa..2d8c428641 100644 --- a/src/pl/ob_pl_type.h +++ b/src/pl/ob_pl_type.h @@ -724,7 +724,7 @@ enum ObPLCursorFlag { REF_BY_REFCURSOR = 1, // this a ref cursor SESSION_CURSOR = 2, // this cursor is alloc in session memory TRANSFERING_RESOURCE = 4, // this cursor is returned by a udf - SYNC_CURSOR = 5, // this cursor from package cursor sync, can not used by this server. + SYNC_CURSOR = 8, // this cursor from package cursor sync, can not used by this server. }; class ObPLCursorInfo { diff --git a/src/pl/ob_pl_user_type.cpp b/src/pl/ob_pl_user_type.cpp index a3784c2868..8e5d54cc7b 100644 --- a/src/pl/ob_pl_user_type.cpp +++ b/src/pl/ob_pl_user_type.cpp @@ -1608,7 +1608,7 @@ int ObPLRecord::deep_copy(ObPLRecord &src, const ObRecordType *record_type = NULL; if (NULL != ns) { OZ (ns->get_user_type(get_id(), user_type, NULL)); - CK (OB_NOT_NULL(user_type)); + OV (OB_NOT_NULL(user_type), OB_ERR_UNEXPECTED, K(get_id()), K(src.get_id())); CK (user_type->is_record_type()); OX (record_type = static_cast(user_type)); } diff --git a/src/sql/ob_spi.cpp b/src/sql/ob_spi.cpp index 6bb929915f..aeace39d67 100644 --- a/src/sql/ob_spi.cpp +++ b/src/sql/ob_spi.cpp @@ -2826,6 +2826,7 @@ int ObSPIService::cursor_open_check(ObPLExecCtx *ctx, } else { CK (OB_NOT_NULL(ctx->allocator_)); OZ (spi_cursor_alloc(*ctx->allocator_, obj)); + OX (obj.set_extend(obj.get_ext(), PL_REF_CURSOR_TYPE)); OX (cursor = reinterpret_cast(obj.get_ext())); } OX (cursor->set_ref_by_refcursor()); @@ -3111,29 +3112,9 @@ int ObSPIService::prepare_cursor_parameters(ObPLExecCtx *ctx, if (OB_FAIL(ret)) { } else if (DECL_PKG == loc) { OZ (spi_set_package_variable(ctx, package_id, formal_param_idxs[i], dummy_result)); - } else if (DECL_SUBPROG == loc) { + } else { OZ (ObPLContext::set_subprogram_var_from_local( session_info, package_id, routine_id, formal_param_idxs[i], dummy_result)); - } else { - int64_t result_idx = formal_param_idxs[i]; - CK (DECL_LOCAL == loc); - CK (result_idx >= 0 && result_idx < ctx->params_->count()); - if (OB_SUCC(ret)) { - ObObjParam ¶m = ctx->params_->at(result_idx); - bool is_ref_cursor = param.is_ref_cursor_type(); - if (!dummy_result.is_ext()) { - dummy_result.ObObj::set_scale(param.get_meta().get_scale()); - dummy_result.set_accuracy(ctx->params_->at(result_idx).get_accuracy()); - param = dummy_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) = dummy_result; - ctx->params_->at(result_idx).set_udt_id(orig_udt_id); - ctx->params_->at(result_idx).set_param_meta(); - } - } } } @@ -5706,8 +5687,7 @@ int ObSPIService::get_result(ObPLExecCtx *ctx, CK (OB_NOT_NULL(table)); if (OB_SUCC(ret) && table->get_count() > 0) { if (implicit_cursor == NULL || !implicit_cursor->get_in_forall()) { - // only clear table data, do not reset collection allocator, - // because fetch rows already copy to collection allocator, in store_result only do shadow copy. + // only clear table data, do not reset collection allocator table->set_count(0); table->set_first(OB_INVALID_INDEX); table->set_last(OB_INVALID_INDEX);