[CP]fix replace expr longtext max len

This commit is contained in:
obdev
2024-02-07 23:24:09 +00:00
committed by ob-robot
parent cb46d55d7f
commit e0398bb9a7
2 changed files with 20 additions and 9 deletions

View File

@ -71,7 +71,7 @@ int ObExprReplace::calc_result_typeN(ObExprResType &type,
OZ(deduce_string_param_calc_type_and_charset(*type_ctx.get_session(), type, params, LS_BYTE));
} else {
if (types_array[0].is_lob()) {
type.set_type(types_array[0].get_type());
type.set_type(ObLongTextType);
} else {
type.set_varchar();
type.set_length_semantics(type_ctx.get_session()->get_actual_nls_length_semantics());
@ -92,6 +92,7 @@ int ObExprReplace::calc_result_typeN(ObExprResType &type,
ObLength from_len = 0;
ObLength to_len = 0;
int64_t result_len = 0;
int64_t max_len = 0;
if (lib::is_oracle_mode()) {
result_len = types_array[0].get_calc_length();
if (param_num == 2 || types_array[2].is_null()) {
@ -113,8 +114,13 @@ int ObExprReplace::calc_result_typeN(ObExprResType &type,
type.set_length(ori_len);
} else {
result_len = ori_len / from_len * to_len + ori_len % from_len;
if (result_len < 0 || result_len > OB_MAX_VARCHAR_LENGTH) {
result_len = OB_MAX_VARCHAR_LENGTH;
if (type.is_lob()) {
max_len = ObAccuracy::DDL_DEFAULT_ACCURACY[type.get_type()].get_length();
} else {
max_len = OB_MAX_VARCHAR_LENGTH;
}
if (result_len < 0 || result_len > max_len) {
result_len = max_len;
}
type.set_length(result_len);
}
@ -128,7 +134,8 @@ int ObExprReplace::replace(ObString &ret_str,
const ObString &text,
const ObString &from,
const ObString &to,
ObExprStringBuf &string_buf)
ObExprStringBuf &string_buf,
const int64_t max_len)
{
int ret = OB_SUCCESS;
ObString dst_str;
@ -169,10 +176,10 @@ int ObExprReplace::replace(ObString &ret_str,
ret_str.reset();
} else if (locations.count() == 0) {
ret_str = text;
} else if (OB_UNLIKELY((OB_MAX_VARCHAR_LENGTH - text.length()) / locations.count() < (to.length() - from.length()))) {
} else if (OB_UNLIKELY((max_len - text.length()) / locations.count() < (to.length() - from.length()))) {
ret = OB_ERR_VARCHAR_TOO_LONG;
LOG_ERROR("Result of replace() was larger than OB_MAX_VARCHAR_LENGTH.",
K(text.length()), K(to.length()), K(from.length()), K(OB_MAX_VARCHAR_LENGTH), K(ret));
LOG_ERROR("Result of replace() was larger than max_len.",
K(text.length()), K(to.length()), K(from.length()), K(max_len), K(locations.count()), K(ret));
ret_str.reset();
} else if (OB_UNLIKELY((tot_length = text.length() + (to.length() - from.length()) * locations.count()) <= 0)) {
// tot_length equals to 0 indicates that length_to is zero and "to" is empty string
@ -267,7 +274,9 @@ int ObExprReplace::eval_replace(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &exp
LOG_WARN("failed to get string data", K(ret), K(expr.args_[2]->datum_meta_));
}
if (OB_SUCC(ret)) {
if (OB_FAIL(replace(res, expr.datum_meta_.cs_type_, text_data, from_data, to_data, temp_allocator))) {
int64_t max_len = ObAccuracy::DDL_DEFAULT_ACCURACY[expr.datum_meta_.get_type()].get_length();
if (OB_FAIL(replace(res, expr.datum_meta_.cs_type_, text_data, from_data,
to_data, temp_allocator, max_len))) {
LOG_WARN("do replace for lob resutl failed", K(ret), K(expr.datum_meta_.type_));
} else if (OB_FAIL(ObTextStringHelper::string_to_templob_result(expr, ctx, expr_datum, res))) {
LOG_WARN("set lob result failed", K(ret));

View File

@ -43,7 +43,9 @@ public:
const common::ObString &text,
const common::ObString &from,
const common::ObString &to,
common::ObExprStringBuf &string_buf);
common::ObExprStringBuf &string_buf,
const int64_t max_len = OB_MAX_VARCHAR_LENGTH);
DECLARE_SET_LOCAL_SESSION_VARS;
private: