bugfix: max varchar length in array

This commit is contained in:
qijiax 2024-12-16 10:15:55 +00:00 committed by ob-robot
parent b9c1eb1bc8
commit 6e609dd4b1
8 changed files with 38 additions and 16 deletions

View File

@ -45,7 +45,7 @@ struct ObArrayAttr {
OB_INLINE bool ob_is_array_supported_type(ObObjType type)
{
return ObUNumberType >= type || ObVarcharType == type || ObCharType == type || ObDecimalIntType == type;
return ObUNumberType >= type || ObVarcharType == type || ObDecimalIntType == type;
}
template<typename T>

View File

@ -308,7 +308,7 @@ int ObSqlCollectionInfo::set_element_meta_info(const std::string &name, uint8_t
meta_info->basic_meta_.set_scale(default_accuracy.get_scale());
break;
case ObStringTC:
if (val <= -1 || val > OB_MAX_ORACLE_VARCHAR_LENGTH) {
if (val <= -1 || val > OB_MAX_VARCHAR_LENGTH / 4) {
ret = OB_ERR_TOO_LONG_COLUMN_LENGTH;
LOG_WARN("data length is invalid", K(ret), K(val));
} else {

View File

@ -477,6 +477,10 @@ int ObArrayExprUtils::deduce_array_element_type(ObExecContext *exec_ctx, ObExprR
ret = OB_NOT_SUPPORTED;
LOG_WARN("unsupported element type", K(ret), K(types_stack[i].get_type()));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "array element type");
} else if (ob_is_varbinary_or_binary(types_stack[i].get_type(), types_stack[i].get_collation_type())) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("array element in binary type isn't supported", K(ret));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "array element in binary type");
} else if (OB_FAIL(ObExprResultTypeUtil::get_deduce_element_type(types_stack[i], elem_type))) {
LOG_WARN("get deduce type failed", K(ret), K(types_stack[i].get_type()), K(elem_type.get_obj_type()), K(i));
}
@ -487,7 +491,7 @@ int ObArrayExprUtils::deduce_array_element_type(ObExecContext *exec_ctx, ObExprR
for (int64_t i = 0; i < param_num && OB_SUCC(ret); i++) {
if (types_stack[i].is_null()) {
} else if (types_stack[i].get_type() != elem_type.get_obj_type()) {
types_stack[i].set_calc_type(elem_type.get_obj_type());
types_stack[i].set_calc_meta(elem_type.get_meta_type());
types_stack[i].set_calc_accuracy(elem_type.get_accuracy());
}
}

View File

@ -175,7 +175,6 @@ int ObExprArrayAppendCommon::eval_append_batch(const ObExpr &expr, ObEvalCtx &ct
ObDatumVector val_datum = expr.args_[1]->locate_expr_datumvector(ctx);
for (int64_t j = 0; OB_SUCC(ret) && j < batch_size; ++j) {
bool is_null_res = false;
int64_t idx = 0;
if (skip.at(j) || eval_flags.at(j)) {
continue;
}

View File

@ -172,6 +172,14 @@ int ObExprArrayMap::calc_result_typeN(ObExprResType& type,
} else {
type.set_collection(subschema_id);
}
} else if (!ob_is_array_supported_type(elem_type.get_obj_type())) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("unsupported element type", K(ret), K(elem_type.get_obj_type()));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "array element type");
} else if (ob_is_varbinary_or_binary(elem_type.get_obj_type(), elem_type.get_collation_type())) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("not supported binary", K(ret));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "array element in binary type");
} else if (OB_FAIL(exec_ctx->get_subschema_id_by_collection_elem_type(ObNestedType::OB_ARRAY_TYPE,
elem_type, subschema_id))) {
LOG_WARN("failed to get collection subschema id", K(ret));

View File

@ -977,6 +977,7 @@ int ObExprResultTypeUtil::get_deduce_element_type(ObExprResType &input_type, ObD
ObObjType type1 = input_type.get_type();
ObObjType type2 = elem_type.get_obj_type();
ObObjType res_type = MERGE_RESULT_TYPE[type1][type2];
ObCollationType coll_type = elem_type.get_collation_type();
ObObjMeta meta;
if (res_type == ObDecimalIntType || res_type == ObNumberType || res_type == ObUNumberType) {
// decimal type isn't supported in array, use double/bigint instead
@ -988,19 +989,18 @@ int ObExprResultTypeUtil::get_deduce_element_type(ObExprResType &input_type, ObD
} else {
meta.set_type(res_type);
}
ObAccuracy acc = ObAccuracy::DDL_DEFAULT_ACCURACY[meta.get_type()];
if (ob_is_collection_sql_type(elem_type.get_obj_type())) {
ret = OB_ERR_ILLEGAL_ARGUMENT_FOR_FUNCTION;
LOG_USER_ERROR(OB_ERR_ILLEGAL_ARGUMENT_FOR_FUNCTION);
} else {
elem_type.set_meta_type(meta);
if (ob_is_string_tc(input_type.get_type())) {
ObLength len = elem_type.get_length();
elem_type.set_accuracy(acc);
if (ob_is_string_tc(type1)) {
// set max len to fix plan cache issue
elem_type.set_length(OB_MAX_ORACLE_VARCHAR_LENGTH);
elem_type.set_length(OB_MAX_VARCHAR_LENGTH / 4);
elem_type.set_collation_type(input_type.get_collation_type());
} else {
elem_type.set_accuracy(acc);
elem_type.set_accuracy(ObAccuracy::DDL_DEFAULT_ACCURACY[meta.get_type()]);
elem_type.set_collation_type(coll_type);
}
}

View File

@ -3770,7 +3770,18 @@ int ObRawExprDeduceType::set_array_agg_result_type(ObAggFunRawExpr &expr,
ret = OB_NOT_SUPPORTED;
LOG_WARN("unsupported element type", K(ret), K(elem_type.get_obj_type()));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "array element type");
} else if (elem_type.get_obj_type() == ObDecimalIntType) {
} else if (ob_is_varbinary_or_binary(elem_type.get_obj_type(), elem_type.get_collation_type())) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("array element in binary type isn't supported", K(ret));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "array element in binary type");
} else if (elem_type.get_obj_type() == ObVarcharType) {
elem_type.set_accuracy(param_expr->get_accuracy());
if (elem_type.get_length() < 0) {
elem_type.set_length(OB_MAX_VARCHAR_LENGTH / 4);
}
} else if (elem_type.get_obj_type() == ObDecimalIntType
|| elem_type.get_obj_type() == ObNumberType
|| elem_type.get_obj_type() == ObUNumberType) {
ObObjMeta meta;
if (param_expr->get_scale() != 0) {
meta.set_double();

View File

@ -446,9 +446,9 @@ int ObResolverUtils::resolve_collection_type_info(const ParseNode &type_node, Ob
ret = OB_NOT_SUPPORTED;
LOG_WARN("not supported element type", K(ret), K(type_node.type_));
} else if (type_node.int32_values_[1]/*is binary*/ && (type_node.type_ == T_CHAR || type_node.type_ == T_VARCHAR)) {
if (OB_FAIL(buf.append(type_node.type_ == T_CHAR ? "BINARY" : "VARBINARY"))) {
LOG_WARN("failed to append type string", K(ret), K(type_node.type_));
}
ret = OB_NOT_SUPPORTED;
LOG_WARN("not supported binary", K(ret), K(type_node.type_));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "array element in binary type");
} else if (is_vector) {
// vector type
if (OB_FAIL(buf.append("VECTOR"))) {
@ -469,10 +469,10 @@ int ObResolverUtils::resolve_collection_type_info(const ParseNode &type_node, Ob
int32_t length = is_bit ? type_node.int16_values_[0]
: (is_char ? type_node.int32_values_[0] : type_node.int16_values_[1]);
int64_t pos = 0;
if (is_char && (length <= -1 || length > OB_MAX_ORACLE_VARCHAR_LENGTH)) {
if (is_char && (length <= -1 || length > OB_MAX_VARCHAR_LENGTH / 4)) {
ret = OB_ERR_TOO_LONG_COLUMN_LENGTH;
LOG_WARN("data length is invalid", K(ret), K(length));
LOG_USER_ERROR(OB_ERR_TOO_LONG_COLUMN_LENGTH, "varchar", static_cast<int>(OB_MAX_ORACLE_VARCHAR_LENGTH));
LOG_USER_ERROR(OB_ERR_TOO_LONG_COLUMN_LENGTH, "varchar", static_cast<int>(OB_MAX_VARCHAR_LENGTH / 4));
} else if (OB_FAIL(databuff_printf(tmp, MAX_LEN, pos, "(%d)",length))) {
LOG_WARN("failed to convert len to string", K(ret), K(length));
} else if (OB_FAIL(buf.append(tmp, pos))) {