diff --git a/src/sql/engine/expr/ob_expr_operator.cpp b/src/sql/engine/expr/ob_expr_operator.cpp index 058ce197de..d6fe19633a 100644 --- a/src/sql/engine/expr/ob_expr_operator.cpp +++ b/src/sql/engine/expr/ob_expr_operator.cpp @@ -1029,7 +1029,7 @@ int ObExprOperator::is_same_kind_type_for_case(const ObExprResType &type1, const return ret; } -// coaesce expr, case when expr +// coalesce expr, case when expr int ObExprOperator::aggregate_result_type_for_case( ObExprResType &type, const ObExprResType *types, @@ -1057,12 +1057,14 @@ int ObExprOperator::aggregate_result_type_for_case( } nth = OB_INVALID_ID == nth ? 0 : nth; const ObExprResType &res_type = types[nth]; - if (need_merge_type && lib::is_oracle_mode() && ObTinyIntType == types[0].get_type()) { + if (need_merge_type && lib::is_oracle_mode() && is_called_in_sql + && ObTinyIntType == types[0].get_type()) { ret = OB_ERR_CALL_WRONG_ARG; LOG_WARN("PLS-00306: wrong number or types of arguments in call", K(ret)); } for (int64_t i = 1; OB_SUCC(ret) && i < param_num; ++i) { - if (need_merge_type && lib::is_oracle_mode() && ObTinyIntType == types[i].get_type()) { + if (need_merge_type && lib::is_oracle_mode() && is_called_in_sql + && ObTinyIntType == types[i].get_type()) { ret = OB_ERR_CALL_WRONG_ARG; LOG_WARN("PLS-00306: wrong number or types of arguments in call", K(ret)); } else if (OB_FAIL(ObExprOperator::is_same_kind_type_for_case(res_type, @@ -1075,7 +1077,15 @@ int ObExprOperator::aggregate_result_type_for_case( } } if (OB_SUCC(ret)) { - if (OB_FAIL(aggregate_result_type_for_merge(type, types, param_num, conn_coll_type, + if (need_merge_type && lib::is_oracle_mode() && ObTinyIntType == types[0].get_type()) { + // bypass `aggregate_result_type_for_merge()` when oracle `case expression` returns boolean, + // also known as ObTinyIntType. `aggregate_result_type_for_merge()` would merge + // ObTinyIntType into ObInt32Type. + type.set_type(ObTinyIntType); + if (OB_FAIL(aggregate_numeric_accuracy_for_merge(type, types, param_num, is_oracle_mode))) { + LOG_WARN("fail to aggregate numeric accuracy", K(ret)); + } + } else if (OB_FAIL(aggregate_result_type_for_merge(type, types, param_num, conn_coll_type, is_oracle_mode, default_length_semantics, session, need_merge_type, skip_null, is_called_in_sql))) { LOG_WARN("fail to aggregate result type", K(ret)); diff --git a/src/sql/rewrite/ob_transform_pre_process.cpp b/src/sql/rewrite/ob_transform_pre_process.cpp index 08edb0ceb9..01aeb4ff2a 100644 --- a/src/sql/rewrite/ob_transform_pre_process.cpp +++ b/src/sql/rewrite/ob_transform_pre_process.cpp @@ -32,6 +32,7 @@ #include "sql/session/ob_sql_session_info.h" #include "share/config/ob_server_config.h" #include "sql/rewrite/ob_transform_utils.h" +#include "sql/resolver/dml/ob_insert_all_stmt.h" #include "sql/resolver/dml/ob_select_stmt.h" #include "sql/resolver/dml/ob_select_resolver.h" #include "sql/resolver/dml/ob_merge_stmt.h" @@ -5346,6 +5347,12 @@ int ObTransformPreProcess::transform_arg_case_expr(ObRawExprFactory &expr_factor LOG_WARN("failed to add param expr", K(ret)); } } // for end + ObRawExpr* tmp_case_expr = static_cast(new_case_expr); + if (OB_SUCC(ret) && + !case_expr->is_called_in_sql() && + OB_FAIL(ObRawExprUtils::set_call_in_pl(tmp_case_expr))) { + LOG_WARN("failed to set call_in_pl flag", K(ret)); + } if (OB_SUCC(ret)) { new_case_expr->set_default_param_expr(case_expr->get_default_param_expr()); if (OB_FAIL(new_case_expr->formalize(&session))) {