Fix system function compatibility bugs
This commit is contained in:
@ -44,6 +44,7 @@ int ObExprMakeSet::calc_result_typeN(ObExprResType &type,
|
||||
} else {
|
||||
// set expected type of parameter
|
||||
ObLength max_len = 0;
|
||||
type_ctx.set_cast_mode(type_ctx.get_cast_mode() | CM_STRING_INTEGER_TRUNC);
|
||||
types[0].set_calc_type(ObIntType);
|
||||
for (int64_t i = 1; i < param_num; ++i) {
|
||||
types[i].set_calc_type(ObVarcharType);
|
||||
|
||||
@ -300,13 +300,37 @@ int ObExprOracleDecode::calc_result_typeN(ObExprResType &type,
|
||||
//deduce string length
|
||||
if (ob_is_string_type(type.get_type()) || ob_is_raw(type.get_type())) {
|
||||
ObLength len = -1;
|
||||
for (int64_t i = 2; i < param_num; i += 2 /*skip conditions */) {
|
||||
if (types_stack[i].get_length() > len) {
|
||||
len = types_stack[i].get_length();
|
||||
if (is_oracle_mode() && (ob_is_string_tc(type.get_type()) || ob_is_raw(type.get_type()))) {
|
||||
ObLength deduced_len = -1;
|
||||
if (OB_ISNULL(type_ctx.get_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session is NULL", K(ret));
|
||||
}
|
||||
for (int64_t i = 2; OB_SUCC(ret) && i < param_num; i += 2 /*skip conditions */) {
|
||||
if (OB_FAIL(ObExprResultTypeUtil::deduce_max_string_length_oracle(type_ctx.get_session()->get_dtc_params(),
|
||||
types_stack[i], type, deduced_len, type.get_length_semantics()))) {
|
||||
LOG_WARN("fail to deduce max string length", K(ret));
|
||||
} else if (deduced_len > len) {
|
||||
len = deduced_len;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && has_default) {
|
||||
if (OB_FAIL(ObExprResultTypeUtil::deduce_max_string_length_oracle(type_ctx.get_session()->get_dtc_params(),
|
||||
types_stack[param_num - 1], type, deduced_len, type.get_length_semantics()))) {
|
||||
LOG_WARN("fail to deduce max string length", K(ret));
|
||||
} else if (deduced_len > len) {
|
||||
len = deduced_len;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 2; i < param_num; i += 2 /*skip conditions */) {
|
||||
if (types_stack[i].get_length() > len) {
|
||||
len = types_stack[i].get_length();
|
||||
}
|
||||
}
|
||||
if (has_default) {
|
||||
len = static_cast<ObLength>(MAX(types_stack[param_num - 1].get_length(), len));
|
||||
}
|
||||
}
|
||||
if (has_default) {
|
||||
len = static_cast<ObLength>(MAX(types_stack[param_num - 1].get_length(), len));
|
||||
}
|
||||
if (all_literal && lib::is_oracle_mode()) {
|
||||
if (OB_FAIL(calc_result_type_for_literal(type, types_stack, param_num, type_ctx))) {
|
||||
|
||||
@ -653,7 +653,7 @@ int ObExprResultTypeUtil::get_arith_calc_type(ObObjType &calc_type,
|
||||
int CHECK_STRING_RES_TYPE_ORACLE(const ObExprResType &type)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!type.is_string_or_lob_locator_type()) {
|
||||
if (!type.is_string_or_lob_locator_type() && !type.is_raw()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("incorrect type of target type", K(ret), K(type));
|
||||
} else if (type.is_blob() || type.is_blob_locator()) {
|
||||
@ -663,7 +663,7 @@ int CHECK_STRING_RES_TYPE_ORACLE(const ObExprResType &type)
|
||||
} else if (!ObCharset::is_valid_collation(type.get_collation_type())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("incorrect charset of target type", K(ret), K(type));
|
||||
} else if (!type.is_clob() && !type.is_clob_locator() &&
|
||||
} else if (!type.is_clob() && !type.is_clob_locator() && !type.is_raw() &&
|
||||
LS_CHAR != type.get_length_semantics() && LS_BYTE != type.get_length_semantics()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("incorrect length_semantics of target type", K(ret), K(type));
|
||||
@ -693,6 +693,8 @@ int ObExprResultTypeUtil::deduce_max_string_length_oracle(const ObDataTypeCastPa
|
||||
ObLengthSemantics length_semantics = target_type.get_length_semantics();
|
||||
if (target_type.is_varchar_or_char() && (LS_BYTE == calc_ls || LS_CHAR == calc_ls)) {
|
||||
length_semantics = calc_ls;
|
||||
} else if (target_type.is_raw()) {
|
||||
length_semantics = LS_BYTE;
|
||||
}
|
||||
if (OB_FAIL(CHECK_STRING_RES_TYPE_ORACLE(target_type))) {
|
||||
LOG_WARN("invalid target_type", K(ret));
|
||||
@ -736,6 +738,9 @@ int ObExprResultTypeUtil::deduce_max_string_length_oracle(const ObDataTypeCastPa
|
||||
// clob to LS_CHAR
|
||||
int64_t mbminlen = ObCharset::get_charset(target_type.get_collation_type())->mbminlen;
|
||||
length = OB_MAX_ORACLE_VARCHAR_LENGTH / mbminlen;
|
||||
} else if (target_type.is_raw()) {
|
||||
//cast not support, return max length
|
||||
length = OB_MAX_ORACLE_RAW_PL_VAR_LENGTH;
|
||||
} else {
|
||||
// clob to LS_BYTE
|
||||
length = OB_MAX_ORACLE_VARCHAR_LENGTH;
|
||||
@ -750,6 +755,12 @@ int ObExprResultTypeUtil::deduce_max_string_length_oracle(const ObDataTypeCastPa
|
||||
}
|
||||
length *= ObCharset::MAX_MB_LEN;
|
||||
length /= ObCharset::get_charset(target_type.get_collation_type())->mbminlen;
|
||||
} else if ((orig_type.is_varchar_or_char() || orig_type.is_nstring())
|
||||
&& target_type.is_raw()) {
|
||||
if (LS_CHAR == orig_type.get_length_semantics()) {
|
||||
length *= ObCharset::get_charset(orig_type.get_collation_type())->mbmaxlen;
|
||||
}
|
||||
length = (length + 1) / 2;
|
||||
} else if (LS_CHAR == orig_type.get_length_semantics()
|
||||
&& LS_BYTE == length_semantics) {
|
||||
// LS_CHAR to LS_BYTE
|
||||
@ -790,7 +801,14 @@ int ObExprResultTypeUtil::deduce_max_string_length_oracle(const ObDataTypeCastPa
|
||||
ascii_bytes = orig_type.get_length();
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (LS_BYTE == length_semantics &&
|
||||
if (target_type.is_raw()) {
|
||||
if (orig_type.is_raw() || orig_type.is_json()) {
|
||||
length = orig_type.get_length();
|
||||
} else {
|
||||
//cast not support, return max length
|
||||
length = OB_MAX_ORACLE_RAW_PL_VAR_LENGTH;
|
||||
}
|
||||
} else if (LS_BYTE == length_semantics &&
|
||||
ObCharset::is_cs_nonascii(target_type.get_collation_type())) {
|
||||
length = (ObLength)(ascii_bytes
|
||||
* ObCharset::get_charset(target_type.get_collation_type())->mbminlen);
|
||||
|
||||
@ -135,9 +135,9 @@ int ObExprSubstringIndex::eval_substring_index(
|
||||
expr_datum.len_ = 0;
|
||||
} else {
|
||||
const ObString m_delim = delim.get_string();
|
||||
// Static cast count to int32, compatible with mysql 5.6,
|
||||
// mysql 5.6 static cast count to int32,
|
||||
// actually this is a bug and fixed in mysql 8.0.
|
||||
int32_t count_val = static_cast<int32_t>(count.get_int());
|
||||
int64_t count_val = count.get_int();
|
||||
ObString res_str;
|
||||
ObExprKMPSearchCtx *kmp_ctx = NULL;
|
||||
const uint64_t op_id = static_cast<uint64_t>(expr.expr_ctx_id_);
|
||||
@ -180,14 +180,14 @@ int ObExprSubstringIndex::eval_substring_index_batch(const ObExpr &expr,
|
||||
continue;;
|
||||
}
|
||||
ObString res_str;
|
||||
int32_t count_val = 0;
|
||||
int64_t count_val = 0;
|
||||
ObDatum &text = expr.args_[0]->locate_expr_datum(ctx, i);
|
||||
ObDatum &delim = expr.args_[1]->locate_expr_datum(ctx, i);
|
||||
ObDatum &count = expr.args_[2]->locate_expr_datum(ctx, i);
|
||||
if (OB_UNLIKELY(text.is_null() || delim.is_null() || count.is_null())) {
|
||||
res[i].set_null();
|
||||
} else if (0 == text.len_ || 0 == delim.len_ ||
|
||||
0 == (count_val = static_cast<int32_t>(count.get_int()))) {
|
||||
0 == (count_val = count.get_int())) {
|
||||
// return empty string if %str or %delim is empty.
|
||||
//重置null flag 防止丢失空串信息
|
||||
res[i].null_ = 0;
|
||||
|
||||
Reference in New Issue
Block a user