Fix a bug of omitting to set res type length for lob exprs

This commit is contained in:
obdev
2023-04-13 08:40:19 +00:00
committed by ob-robot
parent 475b0fa975
commit 3926fdba2f
8 changed files with 37 additions and 4 deletions

View File

@ -38,6 +38,7 @@ int ObExprEmptyClob::calc_result_type0(ObExprResType &type, ObExprTypeCtx &type_
UNUSED(type_ctx);
ObSessionNLSParams nls_param = type_ctx.get_session()->get_session_nls_params();
type.set_clob();
type.set_length(0);
type.set_collation_level(CS_LEVEL_IMPLICIT);
type.set_collation_type(nls_param.nls_collation_);
return OB_SUCCESS;
@ -87,6 +88,7 @@ int ObExprEmptyBlob::calc_result_type0(ObExprResType &type, ObExprTypeCtx &type_
{
UNUSED(type_ctx);
type.set_blob();
type.set_length(0);
type.set_collation_type(CS_TYPE_BINARY);
return OB_SUCCESS;
}

View File

@ -47,6 +47,16 @@ int ObExprToBlob::calc_result_type1(ObExprResType &type,
|| ob_is_string_tc(text.get_type())) {
type.set_blob();
type.set_collation_type(CS_TYPE_BINARY);
if (ob_is_string_tc(text.get_type())) {
ObLength length = text.get_length();
if (LS_CHAR == text.get_length_semantics()) {
length *= ObCharset::get_charset(text.get_collation_type())->mbmaxlen;
}
length = (length / 2) + (length % 2);
type.set_length(length);
} else { // input is blob or raw type
type.set_length(text.get_length());
}
if (ob_is_string_tc(text.get_type())) {
text.set_calc_type(common::ObRawType);
}

View File

@ -17,6 +17,7 @@
#include "objit/common/ob_item_type.h"
#include "lib/oblog/ob_log.h"
#include "sql/engine/expr/ob_expr_lob_utils.h"
#include "sql/engine/expr/ob_expr_result_type_util.h"
namespace oceanbase
{
@ -55,10 +56,25 @@ int ObExprToClob::calc_result_type1(ObExprResType &type,
type.set_clob();
type.set_collation_level(CS_LEVEL_IMPLICIT);
type.set_collation_type(nls_param.nls_collation_);
text.set_calc_collation_type(nls_param.nls_collation_);
if (!text.is_clob()) {
text.set_calc_type(ObVarcharType);
ObLength res_len = -1;
ObExprResType tmp_calc_type; // for deducing res len
tmp_calc_type.set_varchar(); // set calc type of param to tmp_calc_type
tmp_calc_type.set_length_semantics(LS_BYTE); // length_semantics of res type clob is byte
tmp_calc_type.set_collation_type(nls_param.nls_collation_);
if (OB_FAIL(ObExprResultTypeUtil::deduce_max_string_length_oracle(
type_ctx.get_session()->get_dtc_params(), text, tmp_calc_type, res_len))) {
LOG_WARN("fail to deduce result length", K(ret), K(text), K(type));
} else {
text.set_calc_length_semantics(text.is_character_type() ? text.get_length_semantics() : LS_BYTE);
text.set_calc_length(text.is_character_type() ? text.get_length() : res_len);
type.set_length(res_len);
}
} else {
type.set_length(text.get_length());
}
text.set_calc_collation_type(nls_param.nls_collation_);
} else {
ret = OB_ERR_INVALID_TYPE_FOR_OP;
LOG_WARN("wrong type of argument in function to_clob", K(ret), K(text));