Fix ps prepare stage type deduction failure

This commit is contained in:
obdev 2022-12-15 10:37:54 +00:00 committed by ob-robot
parent bd7b419638
commit 2ff985ffdd
6 changed files with 66 additions and 11 deletions

View File

@ -922,6 +922,7 @@ int ObSql::do_real_prepare(const ObString &sql,
context.is_dynamic_sql_ = !context.is_dynamic_sql_ ? !is_inner_sql : context.is_dynamic_sql_;
bool is_from_pl = (NULL != context.secondary_namespace_ || result.is_simple_ps_protocol());
ObPsPrepareStatusGuard ps_status_guard(session, is_from_pl);
ObPlanCacheCtx pc_ctx(sql, true, /*is_ps_mode*/
allocator, context, ectx, session.get_effective_tenant_id());
ParamStore param_store( (ObWrapperAllocator(&allocator)) );

View File

@ -5954,6 +5954,7 @@ int ObOptimizerUtil::try_add_cast_to_set_child_list(ObIAllocator *allocator,
ObSEArray<ObExprResType, 2> types;
ObExprVersion dummy_op(*allocator);
ObCollationType coll_type = CS_TYPE_INVALID;
bool skip_add_cast = false;
if (lib::is_oracle_mode()) {
/*
* Oracle has more strict constraints for data types used in set operator
@ -5972,9 +5973,15 @@ int ObOptimizerUtil::try_add_cast_to_set_child_list(ObIAllocator *allocator,
&& (ob_is_oracle_temporal_type(right_type.get_type())))
|| (left_type.is_urowid() && right_type.is_urowid())
|| (left_type.is_lob() && right_type.is_lob() && !is_distinct))) {
ret = OB_ERR_EXP_NEED_SAME_DATATYPE;
LOG_WARN("expression must have same datatype as corresponding expression", K(ret),
K(i), K(left_type), K(right_type));
if (session_info->is_ps_prepare_stage()) {
skip_add_cast = true;
LOG_WARN("ps prepare stage expression has different datatype", K(i), K(left_type), K(right_type));
} else {
ret = OB_ERR_EXP_NEED_SAME_DATATYPE;
LOG_WARN("expression must have same datatype as corresponding expression", K(ret),
K(session_info->is_ps_prepare_stage()), K(right_type.is_varchar_or_char()),
K(i), K(left_type), K(right_type));
}
} else if (left_type.is_character_type()
&& right_type.is_character_type()
&& (left_type.is_varchar_or_char() != right_type.is_varchar_or_char())) {
@ -5998,7 +6005,7 @@ int ObOptimizerUtil::try_add_cast_to_set_child_list(ObIAllocator *allocator,
}
const ObLengthSemantics length_semantics = session_info->get_actual_nls_length_semantics();
if (OB_FAIL(ret)) {
} else if (to_left_type) {
} else if (to_left_type || skip_add_cast) {
res_type = left_type;
} else if (OB_FAIL(types.push_back(left_type)) || OB_FAIL(types.push_back(right_type))) {
LOG_WARN("failed to push back", K(ret));
@ -6006,9 +6013,15 @@ int ObOptimizerUtil::try_add_cast_to_set_child_list(ObIAllocator *allocator,
LOG_WARN("failed to get collation connection", K(ret));
} else if (OB_FAIL(dummy_op.aggregate_result_type_for_merge(res_type, &types.at(0), 2,
coll_type, is_oracle_mode(), length_semantics, session_info))) {
LOG_WARN("failed to aggregate result type for merge", K(ret));
if (session_info->is_ps_prepare_stage()) {
skip_add_cast = true;
res_type = left_type;
LOG_WARN("failed to deduce type in ps prepare stage", K(types));
} else {
LOG_WARN("failed to aggregate result type for merge", K(ret));
}
}
if (OB_FAIL(ret)) {
if (OB_FAIL(ret) || skip_add_cast) {
} else if (ObMaxType == res_type.get_type()) {
ret = OB_ERR_INVALID_TYPE_FOR_OP;
LOG_WARN("column type incompatible", K(left_type), K(right_type));

View File

@ -32,6 +32,24 @@ using common::ObPsStmtId;
namespace sql
{
class ObPsPrepareStatusGuard final
{
public:
explicit ObPsPrepareStatusGuard(ObSQLSessionInfo &session_info, bool is_from_pl)
: session_info_(session_info)
{
if (!is_from_pl) {
session_info_.set_is_ps_prepare_stage(true);
}
}
~ObPsPrepareStatusGuard()
{
session_info_.set_is_ps_prepare_stage(false);
}
private:
ObSQLSessionInfo &session_info_;
};
class ObPsCache
{
public:

View File

@ -226,6 +226,11 @@ int ObRawExprDeduceType::calc_result_type_with_const_arg(
break;
} // end switch
}
if (OB_FAIL(ret) && my_session_->is_ps_prepare_stage()) {
// the ps prepare stage does not do type deduction, and directly gives a default type.
result_type.set_null();
ret = OB_SUCCESS;
}
}
#undef GET_TYPE_ARRAY
return ret;
@ -396,6 +401,11 @@ int ObRawExprDeduceType::calc_result_type(ObNonTerminalRawExpr &expr,
LOG_WARN("fail to calc result type with const arguments", K(ret));
}
}
if (OB_FAIL(ret) && my_session_->is_ps_prepare_stage()) {
// the ps prepare stage does not do type deduction, and directly gives a default type.
result_type.set_null();
ret = OB_SUCCESS;
}
// check parameters can cast to expected type
if (OB_SUCC(ret)) {
const bool is_oracle_mode = lib::is_oracle_mode();
@ -412,7 +422,8 @@ int ObRawExprDeduceType::calc_result_type(ObNonTerminalRawExpr &expr,
LOG_WARN("PLS-00306: wrong number or types of arguments in call", K(ret));
}
if (OB_FAIL(ret)) {
} else if (from != to && !cast_supported(from, from_cs_type, to, to_cs_type)) {
} else if (from != to && !cast_supported(from, from_cs_type, to, to_cs_type)
&& !my_session_->is_ps_prepare_stage()) {
ret = OB_ERR_INVALID_TYPE_FOR_OP;
LOG_WARN("cast parameter to expected type not supported", K(ret), K(i), K(from), K(to));
} else if (is_oracle_mode && (ob_is_lob_locator(from) || ob_is_text_tc(from))) {
@ -1188,7 +1199,8 @@ int ObRawExprDeduceType::visit(ObAggFunRawExpr &expr)
? from_type
: ObNumberType);
if (from_type != to_type && !cast_supported(from_type, from_cs_type,
to_type, CS_TYPE_BINARY)) {
to_type, CS_TYPE_BINARY)
&& !my_session_->is_ps_prepare_stage()) {
ret = OB_ERR_INVALID_TYPE_FOR_OP;
LOG_WARN("cast to expected type not supported", K(ret), K(from_type), K(to_type));
} else {
@ -1312,7 +1324,8 @@ int ObRawExprDeduceType::visit(ObAggFunRawExpr &expr)
: (T_FUN_GROUP_PERCENTILE_DISC == expr.get_expr_type()
? from_cs_type : CS_TYPE_BINARY);
if (from_type != to_type && !cast_supported(from_type, from_cs_type,
to_type, to_cs_type)) {
to_type, to_cs_type)
&& !my_session_->is_ps_prepare_stage()) {
ret = OB_ERR_INVALID_TYPE_FOR_OP;
LOG_WARN("cast to expected type not supported", K(ret), K(from_type), K(to_type));
} else {
@ -1385,11 +1398,13 @@ int ObRawExprDeduceType::visit(ObAggFunRawExpr &expr)
}
}
if (from_type1 != to_type && !cast_supported(from_type1, from_cs_type1,
to_type, to_cs_type)) {
to_type, to_cs_type)
&& !my_session_->is_ps_prepare_stage()) {
ret = OB_ERR_INVALID_TYPE_FOR_OP;
LOG_WARN("cast to expected type not supported", K(ret), K(from_type1), K(to_type));
} else if (from_type2 != to_type && !cast_supported(from_type2, from_cs_type2,
to_type, to_cs_type)) {
to_type, to_cs_type)
&& !my_session_->is_ps_prepare_stage()) {
ret = OB_ERR_INVALID_TYPE_FOR_OP;
LOG_WARN("cast to expected type not supported", K(ret), K(from_type2), K(to_type));
} else {
@ -2895,6 +2910,10 @@ int ObRawExprDeduceType::try_add_cast_expr(RawExprType &parent,
LOG_WARN("cast to lob type not allowed", K(ret));
}
OZ(parent.replace_param_expr(child_idx, new_expr));
if (OB_FAIL(ret) && my_session_->is_ps_prepare_stage()) {
ret = OB_SUCCESS;
LOG_DEBUG("ps prepare phase ignores type deduce error");
}
}
}
return ret;

View File

@ -168,6 +168,7 @@ ObSQLSessionInfo::ObSQLSessionInfo() :
is_load_data_exec_session_(false),
is_registered_to_deadlock_(false),
pl_exact_err_msg_(),
is_ps_prepare_stage_(false),
got_conn_res_(false),
tx_level_temp_table_(false),
mem_context_(nullptr),

View File

@ -906,6 +906,8 @@ public:
}
bool is_registered_to_deadlock() const { return ATOMIC_LOAD(&is_registered_to_deadlock_); }
void set_registered_to_deadlock(bool state) { ATOMIC_SET(&is_registered_to_deadlock_, state); }
bool is_ps_prepare_stage() const { return is_ps_prepare_stage_; }
void set_is_ps_prepare_stage(bool v) { is_ps_prepare_stage_ = v; }
int get_tenant_audit_trail_type(ObAuditTrailType &at_type)
{
cached_tenant_config_info_.refresh();
@ -1080,6 +1082,7 @@ private:
// 记录session是否注册过死锁检测的信息
bool is_registered_to_deadlock_;
ObSqlString pl_exact_err_msg_;
bool is_ps_prepare_stage_;
// Record whether this session has got connection resource, which means it increased connections count.
// It's used for on_user_disconnect.
// No matter whether apply for resource successfully, a session will call on_user_disconnect when disconnect.