[CP] [to #53709570] fix udt parameter & function out value in ps anonymous block

This commit is contained in:
obdev 2024-02-08 16:41:14 +00:00 committed by ob-robot
parent 7df6c7b6fb
commit f351aa3c6a
3 changed files with 62 additions and 27 deletions

View File

@ -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<ObConstRawExpr *>(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<ObConstRawExpr *>(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<ObConstRawExpr*>(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<ObPLVar*>(var))->set_type(*type));
OX ((const_cast<ObPLVar*>(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<ObPLVar*>(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<ObPLVar*>(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)) {

View File

@ -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<int64_t>& formal_params,
ObPLCursor &cursor,

View File

@ -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<ObConstRawExpr*>(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<ObRoutineParam*>(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_, &param_type));
}
} else if (T_OP_GET_PACKAGE_VAR == iexpr->get_expr_type()) {
const ObSysFunRawExpr *f_expr = static_cast<const ObSysFunRawExpr *>(iexpr);
uint64_t pkg_id = OB_INVALID_ID;