to issue<2024102900104845408>:fix subquery in pl issue
This commit is contained in:
parent
081f359018
commit
a9d86c2315
@ -10465,6 +10465,7 @@ int ObPLResolver::transform_subquery_expr(const ParseNode *node,
|
||||
}
|
||||
|
||||
OX (subquery_expr->set_subquery_result_type(result_type));
|
||||
OX (subquery_expr->set_enum_set_values(expected_type->get_type_info()));
|
||||
OX (expr = subquery_expr);
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
|
@ -457,6 +457,7 @@ int ObExprGeneratorImpl::visit(ObPlQueryRefRawExpr &expr)
|
||||
OX (pl_subquery->set_stmt_type(expr.get_stmt_type()));
|
||||
OZ (pl_subquery->deep_copy_route_sql(expr.get_route_sql()));
|
||||
OX (pl_subquery->set_result_type(expr.get_subquery_result_type()));
|
||||
OZ (pl_subquery->set_type_info(expr.get_enum_set_values()));
|
||||
if (OB_SUCC(ret) && expr.is_ignore_fail()) {
|
||||
pl_subquery->set_ignore_fail();
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ namespace sql
|
||||
|
||||
OB_SERIALIZE_MEMBER(
|
||||
(ObExprOpSubQueryInPl, ObFuncExprOperator),
|
||||
id_, type_, route_sql_, result_type_, is_ignore_fail_, ps_sql_);
|
||||
id_, type_, route_sql_, result_type_, is_ignore_fail_, ps_sql_, type_info_);
|
||||
|
||||
|
||||
ObExprOpSubQueryInPl::ObExprOpSubQueryInPl(common::ObIAllocator &alloc)
|
||||
@ -44,10 +44,39 @@ ObExprOpSubQueryInPl::ObExprOpSubQueryInPl(common::ObIAllocator &alloc)
|
||||
route_sql_(ObString()),
|
||||
result_type_(),
|
||||
is_ignore_fail_(false),
|
||||
allocator_(alloc) {}
|
||||
allocator_(alloc),
|
||||
type_info_() {}
|
||||
|
||||
ObExprOpSubQueryInPl::~ObExprOpSubQueryInPl() {}
|
||||
|
||||
int ObExprOpSubQueryInPl::deep_copy_type_info(common::ObIArray<common::ObString>& dst_type_info,
|
||||
common::ObIAllocator &allocator,
|
||||
const common::ObIArray<common::ObString>& type_info)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_SUCC(ret)) {
|
||||
dst_type_info.reset();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < type_info.count(); ++i) {
|
||||
const ObString &info = type_info.at(i);
|
||||
if (OB_UNLIKELY(0 == info.length())) {
|
||||
if (OB_FAIL(dst_type_info.push_back(ObString(0, NULL)))) {
|
||||
LOG_WARN("fail to push back info", K(i), K(info), K(ret));
|
||||
}
|
||||
} else {
|
||||
char *buf = NULL;
|
||||
if (OB_ISNULL(buf = static_cast<char*>(allocator.alloc(info.length())))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate memory", K(i), K(info), K(ret));
|
||||
} else if (FALSE_IT(MEMCPY(buf, info.ptr(), info.length()))) {
|
||||
} else if (OB_FAIL(dst_type_info.push_back(ObString(info.length(), buf)))) {
|
||||
LOG_WARN("fail to push back info", K(i), K(info), K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprOpSubQueryInPl::assign(const ObExprOperator &other)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -64,6 +93,7 @@ int ObExprOpSubQueryInPl::assign(const ObExprOperator &other)
|
||||
OX (this->result_type_ = tmp_other->result_type_);
|
||||
OZ (deep_copy_route_sql(tmp_other->route_sql_));
|
||||
OX (this->is_ignore_fail_ = tmp_other->is_ignore_fail_);
|
||||
OZ (ObExprOpSubQueryInPl::deep_copy_type_info(type_info_, allocator_, tmp_other->type_info_));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -233,7 +263,8 @@ int ObExprOpSubQueryInPl::eval_subquery(const ObExpr &expr,
|
||||
result,
|
||||
info->result_type_,
|
||||
conv_res,
|
||||
info->is_ignore_fail_));
|
||||
info->is_ignore_fail_,
|
||||
&info->type_info_));
|
||||
if (OB_FAIL(ret)) {
|
||||
LOG_WARN("convert type error", K(ret));
|
||||
} else {
|
||||
@ -342,7 +373,8 @@ OB_DEF_SERIALIZE(ObExprPlSubQueryInfo)
|
||||
route_sql_,
|
||||
result_type_,
|
||||
is_ignore_fail_,
|
||||
ps_sql_);
|
||||
ps_sql_,
|
||||
type_info_);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -355,7 +387,8 @@ OB_DEF_DESERIALIZE(ObExprPlSubQueryInfo)
|
||||
route_sql_,
|
||||
result_type_,
|
||||
is_ignore_fail_,
|
||||
ps_sql_);
|
||||
ps_sql_,
|
||||
type_info_);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -368,10 +401,13 @@ OB_DEF_SERIALIZE_SIZE(ObExprPlSubQueryInfo)
|
||||
route_sql_,
|
||||
result_type_,
|
||||
is_ignore_fail_,
|
||||
ps_sql_);
|
||||
ps_sql_,
|
||||
type_info_);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ObExprPlSubQueryInfo::deep_copy(common::ObIAllocator &allocator,
|
||||
const ObExprOperatorType type,
|
||||
ObIExprExtraInfo *&copied_info) const
|
||||
@ -385,6 +421,7 @@ int ObExprPlSubQueryInfo::deep_copy(common::ObIAllocator &allocator,
|
||||
|
||||
OZ(ob_write_string(allocator, route_sql_, other.route_sql_, true));
|
||||
OZ(ob_write_string(allocator, ps_sql_, other.ps_sql_, true));
|
||||
OZ(ObExprOpSubQueryInPl::deep_copy_type_info(other.type_info_, allocator, type_info_));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -402,6 +439,7 @@ int ObExprPlSubQueryInfo::from_raw_expr(RE &raw_expr, ObIAllocator &alloc)
|
||||
|
||||
OZ(ob_write_string(alloc, subquery_expr.get_route_sql(), route_sql_, true));
|
||||
OZ(ob_write_string(alloc, subquery_expr.get_route_sql(), ps_sql_, true));
|
||||
OZ(ObExprOpSubQueryInPl::deep_copy_type_info(type_info_, alloc, subquery_expr.get_enum_set_values()));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,8 @@ public:
|
||||
type_(stmt::T_NONE),
|
||||
route_sql_(ObString()),
|
||||
result_type_(),
|
||||
is_ignore_fail_(false) {}
|
||||
is_ignore_fail_(false),
|
||||
type_info_() {}
|
||||
|
||||
virtual int deep_copy(common::ObIAllocator &allocator,
|
||||
const ObExprOperatorType type,
|
||||
@ -50,6 +51,7 @@ public:
|
||||
common::ObString route_sql_;
|
||||
sql::ObExprResType result_type_;
|
||||
bool is_ignore_fail_;
|
||||
common::ObSEArray<common::ObString, 4> type_info_;
|
||||
};
|
||||
|
||||
class ObExprOpSubQueryInPl : public ObFuncExprOperator
|
||||
@ -69,6 +71,10 @@ public:
|
||||
ObFuncExprOperator::reset();
|
||||
}
|
||||
|
||||
static int deep_copy_type_info(common::ObIArray<common::ObString>& dst_type_info,
|
||||
common::ObIAllocator &allocator,
|
||||
const common::ObIArray<common::ObString>& type_info);
|
||||
|
||||
virtual int assign(const ObExprOperator &other);
|
||||
|
||||
int deep_copy_route_sql(const common::ObString &v)
|
||||
@ -86,6 +92,11 @@ public:
|
||||
inline void set_result_type(ObExprResType type) { result_type_ = type; }
|
||||
inline void set_ignore_fail() { is_ignore_fail_ = true; }
|
||||
|
||||
int set_type_info(const common::ObIArray<common::ObString>& type_info)
|
||||
{
|
||||
return deep_copy_type_info(type_info_, allocator_, type_info);
|
||||
}
|
||||
|
||||
virtual int cg_expr(ObExprCGCtx &op_cg_ctx,
|
||||
const ObRawExpr &raw_expr, ObExpr &rt_expr) const override;
|
||||
|
||||
@ -105,6 +116,7 @@ private:
|
||||
ObExprResType result_type_;
|
||||
bool is_ignore_fail_;
|
||||
common::ObIAllocator &allocator_;
|
||||
common::ObSEArray<common::ObString, 4> type_info_;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObExprOpSubQueryInPl);
|
||||
|
@ -758,7 +758,8 @@ int ObSPIService::spi_convert(ObSQLSessionInfo &session,
|
||||
ObObj &src,
|
||||
const ObExprResType &dst_type,
|
||||
ObObj &dst,
|
||||
bool ignore_fail)
|
||||
bool ignore_fail,
|
||||
const ObIArray<ObString> *type_info)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObCastMode cast_mode = CM_NONE;
|
||||
@ -776,7 +777,7 @@ int ObSPIService::spi_convert(ObSQLSessionInfo &session,
|
||||
if (dst_type.is_null() || dst_type.is_unknown() || dst_type.is_ext()) {
|
||||
OX (dst = src);
|
||||
} else {
|
||||
OZ (ObExprColumnConv::convert_with_null_check(dst, src, dst_type, is_strict, cast_ctx, NULL));
|
||||
OZ (ObExprColumnConv::convert_with_null_check(dst, src, dst_type, is_strict, cast_ctx, type_info));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -440,7 +440,9 @@ public:
|
||||
int64_t expr_idx,
|
||||
ObObjParam *result);
|
||||
static int spi_convert(ObSQLSessionInfo &session, ObIAllocator &allocator,
|
||||
ObObj &src, const ObExprResType &result_type, ObObj &dst, bool ignore_fail = false);
|
||||
ObObj &src, const ObExprResType &result_type, ObObj &dst,
|
||||
bool ignore_fail = false,
|
||||
const ObIArray<ObString> *type_info = nullptr);
|
||||
static int spi_convert(ObSQLSessionInfo *session, ObIAllocator *allocator,
|
||||
ObObjParam &src, const ObExprResType &result_type, ObObjParam &result);
|
||||
static int spi_convert_objparam(pl::ObPLExecCtx *ctx, ObObjParam *src, const int64_t result_idx, ObObjParam *result, bool need_set);
|
||||
|
@ -4898,7 +4898,8 @@ int ObRawExprUtils::create_type_to_str_expr(ObRawExprFactory &expr_factory,
|
||||
&& !src_expr->is_sys_func_expr()
|
||||
&& !src_expr->is_udf_expr()
|
||||
&& !src_expr->is_win_func_expr()
|
||||
&& !(src_expr->is_op_expr() && ob_is_enum_or_set_type(src_expr->get_data_type())))) {
|
||||
&& !(src_expr->is_op_expr() && ob_is_enum_or_set_type(src_expr->get_data_type())))
|
||||
&& src_expr->get_expr_type() != T_FUN_SUBQUERY) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("src_expr should be terminal expr or func expr", KPC(src_expr), K(ret));
|
||||
} else if (FALSE_IT(data_type = src_expr->get_data_type())) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user