From f351aa3c6a8e2fd07684893a0a15bf614258605e Mon Sep 17 00:00:00 2001 From: obdev Date: Thu, 8 Feb 2024 16:41:14 +0000 Subject: [PATCH] [CP] [to #53709570] fix udt parameter & function out value in ps anonymous block --- src/pl/ob_pl_resolver.cpp | 62 +++++++++++++--------- src/pl/ob_pl_resolver.h | 4 +- src/sql/resolver/expr/ob_raw_expr_util.cpp | 23 ++++++++ 3 files changed, 62 insertions(+), 27 deletions(-) diff --git a/src/pl/ob_pl_resolver.cpp b/src/pl/ob_pl_resolver.cpp index 57b3ecbee..d042ca481 100644 --- a/src/pl/ob_pl_resolver.cpp +++ b/src/pl/ob_pl_resolver.cpp @@ -3750,17 +3750,17 @@ int ObPLResolver::resolve_question_mark_node( return ret; } -bool ObPLResolver::is_question_mark_value(ObRawExpr *into_expr) +bool ObPLResolver::is_question_mark_value(ObRawExpr *into_expr, ObPLBlockNS *ns) { bool ret = false; if (OB_NOT_NULL(into_expr) && T_QUESTIONMARK == into_expr->get_expr_type() && (static_cast(into_expr))->get_value().is_unknown() - && OB_NOT_NULL(current_block_) - && OB_NOT_NULL(current_block_->get_symbol_table())) { + && OB_NOT_NULL(ns) + && OB_NOT_NULL(ns->get_symbol_table())) { const ObPLVar *var = NULL; int64_t idx = (static_cast(into_expr))->get_value().get_unknown(); - if (OB_NOT_NULL(var = current_block_->get_symbol_table()->get_symbol(idx))) { + if (OB_NOT_NULL(var = ns->get_symbol_table()->get_symbol(idx))) { if (var->get_name().prefix_match(ANONYMOUS_ARG)) { ret = true; } @@ -3769,21 +3769,33 @@ bool ObPLResolver::is_question_mark_value(ObRawExpr *into_expr) return ret; } -int ObPLResolver::set_question_mark_type(ObRawExpr *into_expr, const ObPLDataType *type) +int ObPLResolver::set_question_mark_type(ObRawExpr *into_expr, ObPLBlockNS *ns, const ObPLDataType *type) { int ret = OB_SUCCESS; ObConstRawExpr *const_expr = NULL; const ObPLVar *var = NULL; + ObExprResType res_type; CK (OB_NOT_NULL(into_expr)); CK (OB_NOT_NULL(type)); + CK (OB_NOT_NULL(ns)); CK (T_QUESTIONMARK == into_expr->get_expr_type()); CK (OB_NOT_NULL(const_expr = static_cast(into_expr))); - CK (OB_NOT_NULL(current_block_->get_symbol_table())); - CK (OB_NOT_NULL(var = current_block_ - ->get_symbol_table()->get_symbol(const_expr->get_value().get_unknown()))); + CK (OB_NOT_NULL(ns->get_symbol_table())); + CK (OB_NOT_NULL(var = ns->get_symbol_table()->get_symbol(const_expr->get_value().get_unknown()))); CK (var->get_name().prefix_match(ANONYMOUS_ARG)); OX ((const_cast(var))->set_type(*type)); OX ((const_cast(var))->set_readonly(false)); + if (OB_FAIL(ret)) { + } else if (type->is_obj_type()) { + CK (OB_NOT_NULL(type->get_data_type())); + OX (res_type.set_meta(type->get_data_type()->get_meta_type())); + OX (res_type.set_accuracy(type->get_data_type()->get_accuracy())); + } else { + OX (res_type.set_ext()); + OX (res_type.set_extend_type(type->get_type())); + OX (res_type.set_udt_id(type->get_user_type_id())); + } + OX (into_expr->set_result_type(res_type)); return ret; } @@ -3943,19 +3955,19 @@ int ObPLResolver::resolve_assign(const ObStmtNodeTree *parse_tree, ObPLAssignStm } } // 目标是QuestionMark, 需要设置目标的类型, 因为QuestionMark默认是无类型的, 在赋值时确定类型 - if (OB_SUCC(ret) && is_question_mark_value(into_expr)) { + if (OB_SUCC(ret) && is_question_mark_value(into_expr, &(current_block_->get_namespace()))) { if (value_expr->get_result_type().is_ext()) { const ObUserDefinedType *user_type = NULL; OZ (current_block_->get_namespace().get_pl_data_type_by_id( value_expr->get_result_type().get_udt_id(), user_type)); - OZ (set_question_mark_type(into_expr, user_type)); + OZ (set_question_mark_type(into_expr, &(current_block_->get_namespace()), user_type)); } else { ObDataType data_type; ObPLDataType pl_type; OX (data_type.set_meta_type(value_expr->get_result_type())); OX (data_type.set_accuracy(value_expr->get_result_type().get_accuracy())); OX (pl_type.set_data_type(data_type)); - OX (set_question_mark_type(into_expr, &pl_type)); + OX (set_question_mark_type(into_expr, &(current_block_->get_namespace()), &pl_type)); } } } else { @@ -8303,8 +8315,9 @@ int ObPLResolver::resolve_fetch( !right->get_data_type()->get_meta_type().is_ext()) { if (right->get_data_type()->get_meta_type().is_null() && stmt->get_into().count() > i && - is_question_mark_value(func.get_expr(stmt->get_into(i)))) { - OZ (set_question_mark_type(func.get_expr(stmt->get_into(i)), left)); + is_question_mark_value(func.get_expr(stmt->get_into(i)), &(current_block_->get_namespace()))) { + OZ (set_question_mark_type( + func.get_expr(stmt->get_into(i)), &(current_block_->get_namespace()), left)); } else { CK (OB_NOT_NULL(left->get_data_type())); OX (is_compatible = cast_supported(left->get_data_type()->get_obj_type(), @@ -11966,18 +11979,17 @@ int ObPLResolver::resolve_udf_info( ObExprResType result_type; CK (OB_NOT_NULL(var = table->get_symbol(position))); if (OB_SUCC(ret) && var->is_readonly()) { - if (var->get_name().prefix_match(ANONYMOUS_ARG)) { - ObPLVar* shadow_var = const_cast(var); - ObIRoutineParam *iparam = NULL; - OX (shadow_var->set_readonly(false)); - CK (OB_NOT_NULL(routine_info)); - OZ (routine_info->get_routine_param(i, iparam)); - if (OB_SUCC(ret) && iparam->is_inout_param()) { - shadow_var->set_name(ANONYMOUS_INOUT_ARG); - } - } else { - ret = OB_ERR_VARIABLE_IS_READONLY; - LOG_WARN("variable is read only", K(ret), K(position), KPC(var)); + ret = OB_ERR_VARIABLE_IS_READONLY; + LOG_WARN("variable is read only", K(ret), K(position), KPC(var)); + } + if (OB_SUCC(ret) && var->get_name().prefix_match(ANONYMOUS_ARG)) { + ObPLVar* shadow_var = const_cast(var); + ObIRoutineParam *iparam = NULL; + OX (shadow_var->set_readonly(false)); + CK (OB_NOT_NULL(routine_info)); + OZ (routine_info->get_routine_param(i, iparam)); + if (OB_SUCC(ret) && iparam->is_inout_param()) { + shadow_var->set_name(ANONYMOUS_INOUT_ARG); } } if (OB_SUCC(ret)) { diff --git a/src/pl/ob_pl_resolver.h b/src/pl/ob_pl_resolver.h index c10ef3c26..d23ffa29e 100644 --- a/src/pl/ob_pl_resolver.h +++ b/src/pl/ob_pl_resolver.h @@ -451,6 +451,8 @@ public: ObProcType &routine_type, const ObPLDataType &ret_type); static int build_pl_integer_type(ObPLIntegerType type, ObPLDataType &data_type); + static bool is_question_mark_value(ObRawExpr *into_expr, ObPLBlockNS *ns); + static int set_question_mark_type(ObRawExpr *into_expr, ObPLBlockNS *ns, const ObPLDataType *type); int get_caller_accessor_item( const ObPLStmtBlock *caller, AccessorItem &caller_item); @@ -1060,8 +1062,6 @@ private: inline void set_item_type(ObItemType item_type) { item_type_ = item_type; } int resolve_question_mark_node(const ObStmtNodeTree *into_node, ObRawExpr *&into_expr); - bool is_question_mark_value(ObRawExpr *into_expr); - int set_question_mark_type(ObRawExpr *into_expr, const ObPLDataType *type); int check_cursor_formal_params(const ObIArray& formal_params, ObPLCursor &cursor, diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index a947957ec..8d458b608 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -1167,10 +1167,33 @@ do { 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); + pl::ObPLDataType param_type; CK (OB_NOT_NULL(c_expr)); CK (c_expr->get_value().is_unknown()); OZ (udf_raw_expr->add_param_desc( ObUDFParamDesc(ObUDFParamDesc::LOCAL_OUT, c_expr->get_value().get_unknown()))); + if (OB_FAIL(ret) || !pl::ObPLResolver::is_question_mark_value(iexpr, params.secondary_namespace_)) { + // do nothing ... + } else { + if (iparam->is_schema_routine_param()) { + ObRoutineParam *param = static_cast(iparam); + CK (OB_NOT_NULL(param)); + CK (OB_NOT_NULL(params.schema_checker_)); + CK (OB_NOT_NULL(params.schema_checker_->get_schema_guard())); + CK (OB_NOT_NULL(params.session_info_)); + CK (OB_NOT_NULL(params.allocator_)); + CK (OB_NOT_NULL(params.sql_proxy_)); + OZ (pl::ObPLDataType::transform_from_iparam(param, + *(params.schema_checker_->get_schema_guard()), + *(params.session_info_), + *(params.allocator_), + *(params.sql_proxy_), + param_type)); + } else { + param_type = iparam->get_pl_data_type(); + } + OZ (pl::ObPLResolver::set_question_mark_type(iexpr, params.secondary_namespace_, ¶m_type)); + } } else if (T_OP_GET_PACKAGE_VAR == iexpr->get_expr_type()) { const ObSysFunRawExpr *f_expr = static_cast(iexpr); uint64_t pkg_id = OB_INVALID_ID;