Fix ps prepare stage type deduction failure
This commit is contained in:
parent
bd7b419638
commit
2ff985ffdd
@ -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)) );
|
||||
|
@ -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));
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user