[ARRAY] fix arr column conv cast

This commit is contained in:
obdev 2024-09-18 05:59:46 +00:00 committed by ob-robot
parent 3fc8183f60
commit eec9c0a530
6 changed files with 54 additions and 18 deletions

View File

@ -614,6 +614,8 @@ OB_INLINE int ObExprValuesOp::calc_next_row()
if (OB_FAIL(eval_values_op_dynamic_cast_to_lob(real_src_expr, src_obj_meta, dst_expr))) {
LOG_WARN("fail to dynamic cast to lob types", K(dst_expr->datum_meta_),
K(real_src_expr), K(cm_), K(ret));
ObString column_name = MY_SPEC.column_names_.at(col_idx);
ret = ObDMLService::log_user_error_inner(ret, row_num, column_name, ctx_);
} else {
dst_expr->set_evaluated_projected(eval_ctx_);
}

View File

@ -14,13 +14,12 @@
#include "ob_array_cast.h"
#include "lib/json_type/ob_json_tree.h"
#include "lib/json_type/ob_json_parse.h"
#include "share/object/ob_obj_cast.h"
namespace oceanbase {
namespace sql {
int ObVectorDataCast::cast(common::ObIAllocator &alloc, ObIArrayType *src, const ObCollectionTypeBase *elem_type,
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type)
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type, ObCastMode mode)
{
int ret = OB_SUCCESS;
const ObCollectionBasicType *src_type = dynamic_cast<const ObCollectionBasicType *>(elem_type);
@ -43,7 +42,7 @@ int ObVectorDataCast::cast(common::ObIAllocator &alloc, ObIArrayType *src, const
} else {
ObObjType dst_obj_type = dst_type->basic_meta_.get_obj_type();
ObObj res;
ObCastCtx cast_ctx(&alloc, NULL, CM_NONE, ObCharset::get_system_collation());
ObCastCtx cast_ctx(&alloc, NULL, mode, ObCharset::get_system_collation());
if (OB_FAIL(ObObjCaster::to_type(dst_obj_type, cast_ctx, src_elem, res))) {
LOG_WARN("failed to cast number to double type", K(ret));
} else {
@ -58,7 +57,7 @@ int ObVectorDataCast::cast(common::ObIAllocator &alloc, ObIArrayType *src, const
}
int ObArrayFixedSizeCast::cast(common::ObIAllocator &alloc, ObIArrayType *src, const ObCollectionTypeBase *elem_type,
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type)
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type, ObCastMode mode)
{
int ret = OB_SUCCESS;
const ObCollectionBasicType *src_type = dynamic_cast<const ObCollectionBasicType *>(elem_type);
@ -75,7 +74,7 @@ int ObArrayFixedSizeCast::cast(common::ObIAllocator &alloc, ObIArrayType *src, c
}
} else if (OB_FAIL(ObArrayCastUtils::cast_get_element(src, src_type, i, src_elem))) {
LOG_WARN("failed to get cast element", K(ret), K(i));
} else if (OB_FAIL(ObArrayCastUtils::cast_add_element(alloc, src_elem, dst, dst_type))) {
} else if (OB_FAIL(ObArrayCastUtils::cast_add_element(alloc, src_elem, dst, dst_type, mode))) {
LOG_WARN("failed to cast and add element", K(ret));
}
}
@ -174,10 +173,10 @@ int ObArrayCastUtils::cast_get_element(ObIArrayType *src, const ObCollectionBasi
}
int ObArrayCastUtils::cast_add_element(common::ObIAllocator &alloc, ObObj &src_elem,
ObIArrayType *dst, const ObCollectionBasicType *dst_elem_type)
ObIArrayType *dst, const ObCollectionBasicType *dst_elem_type, ObCastMode mode)
{
int ret = OB_SUCCESS;
ObCastCtx cast_ctx(&alloc, NULL, CM_NONE, ObCharset::get_system_collation());
ObCastCtx cast_ctx(&alloc, NULL, mode, ObCharset::get_system_collation());
ObObjType dst_obj_type = dst_elem_type->basic_meta_.get_obj_type();
ObObj res;
if (OB_FAIL(ObObjCaster::to_type(dst_obj_type, cast_ctx, src_elem, res))) {
@ -443,7 +442,7 @@ int ObArrayCastUtils::string_cast(common::ObIAllocator &alloc, ObString &arr_tex
}
int ObArrayBinaryCast::cast(common::ObIAllocator &alloc, ObIArrayType *src, const ObCollectionTypeBase *elem_type,
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type)
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type, ObCastMode mode)
{
int ret = OB_SUCCESS;
const ObCollectionBasicType *src_type = dynamic_cast<const ObCollectionBasicType *>(elem_type);
@ -468,7 +467,7 @@ int ObArrayBinaryCast::cast(common::ObIAllocator &alloc, ObIArrayType *src, cons
}else if (elem_len_max < src_elem.get_string_len()) {
ret = OB_ERR_DATA_TOO_LONG;
LOG_WARN("varchar type length is too long", K(ret), K(i), K(elem_len_max), K(src_elem.get_string_len()));
} else if (OB_FAIL(ObArrayCastUtils::cast_add_element(alloc, src_elem, dst, dst_type))) {
} else if (OB_FAIL(ObArrayCastUtils::cast_add_element(alloc, src_elem, dst, dst_type, mode))) {
LOG_WARN("failed to cast and add element", K(ret));
}
}
@ -477,7 +476,7 @@ int ObArrayBinaryCast::cast(common::ObIAllocator &alloc, ObIArrayType *src, cons
}
int ObArrayNestedCast::cast(common::ObIAllocator &alloc, ObIArrayType *src, const ObCollectionTypeBase *elem_type,
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type)
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type, ObCastMode mode)
{
int ret = OB_SUCCESS;
const ObCollectionArrayType *src_type = dynamic_cast<const ObCollectionArrayType *>(elem_type);

View File

@ -14,6 +14,7 @@
#define OCEANBASE_OB_ARRAY_CAST_
#include "lib/udt/ob_collection_type.h"
#include "lib/udt/ob_array_type.h"
#include "share/object/ob_obj_cast.h"
namespace oceanbase {
namespace sql {
@ -29,7 +30,7 @@ public:
ObArrayTypeCast() {};
virtual ~ObArrayTypeCast() {};
virtual int cast(common::ObIAllocator &alloc, ObIArrayType *src, const ObCollectionTypeBase *elem_type,
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type) = 0;
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type, ObCastMode mode = 0) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(ObArrayTypeCast);
};
@ -38,14 +39,14 @@ class ObArrayFixedSizeCast : public ObArrayTypeCast
{
public:
int cast(common::ObIAllocator &alloc, ObIArrayType *src, const ObCollectionTypeBase *elem_type,
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type);
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type, ObCastMode mode = 0);
};
class ObVectorDataCast : public ObArrayTypeCast
{
public:
int cast(common::ObIAllocator &alloc, ObIArrayType *src, const ObCollectionTypeBase *elem_type,
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type);
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type, ObCastMode mode = 0);
uint32_t dim_cnt_;
};
@ -53,14 +54,14 @@ class ObArrayBinaryCast : public ObArrayTypeCast
{
public:
int cast(common::ObIAllocator &alloc, ObIArrayType *src, const ObCollectionTypeBase *elem_type,
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type);
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type, ObCastMode mode = 0);
};
class ObArrayNestedCast : public ObArrayTypeCast
{
public :
int cast(common::ObIAllocator &alloc, ObIArrayType *src, const ObCollectionTypeBase *elem_type,
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type);
ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type, ObCastMode mode = 0);
}
;
@ -71,7 +72,7 @@ class ObArrayCastUtils
public:
static int string_cast(common::ObIAllocator &alloc, ObString &arr_text, ObIArrayType *&dst, const ObCollectionTypeBase *dst_elem_type);
static int cast_get_element(ObIArrayType *src, const ObCollectionBasicType *elem_type, uint32_t idx, ObObj &src_elem);
static int cast_add_element(common::ObIAllocator &alloc, ObObj &src_elem, ObIArrayType *dst, const ObCollectionBasicType *dst_elem_type);
static int cast_add_element(common::ObIAllocator &alloc, ObObj &src_elem, ObIArrayType *dst, const ObCollectionBasicType *dst_elem_type, ObCastMode mode);
static int add_json_node_to_array(common::ObIAllocator &alloc, ObJsonNode &j_node, const ObCollectionTypeBase *elem_type, ObIArrayType *dst);
};

View File

@ -9634,7 +9634,7 @@ CAST_FUNC_NAME(collection, collection)
} else if (OB_FAIL(ObArrayTypeCastFactory::alloc(temp_allocator, *arr_type,
*dst_arr_type, arr_cast))) {
LOG_WARN("alloc array cast failed", K(ret), K(src_coll_info));
} else if (OB_FAIL(arr_cast->cast(temp_allocator, arr_src, elem_type, arr_dst, dst_elem_type))) {
} else if (OB_FAIL(arr_cast->cast(temp_allocator, arr_src, elem_type, arr_dst, dst_elem_type, expr.extra_))) {
LOG_WARN("array element cast failed", K(ret), K(*src_coll_info), K(*dst_coll_info));
if (ret == OB_ERR_ARRAY_TYPE_MISMATCH) {
ObString dst_def = dst_coll_info->get_def_string();

View File

@ -182,6 +182,9 @@ int ObExprArrayContains::calc_result_type2(ObExprResType &type,
LOG_WARN("failed to eval args", K(ret)); \
} else if (OB_FAIL(ObArrayExprUtils::get_array_obj(tmp_allocator, ctx, meta_id, datum->get_string(), arr_obj))) { \
LOG_WARN("construct array obj failed", K(ret)); \
} else if (datum_val->is_null()) { \
bool contains_null = arr_obj->contain_null(); \
res.set_bool(contains_null); \
} else if (FALSE_IT(val = datum_val->GET_FUNC())) { \
} else if (OB_FAIL(ObArrayUtil::contains(*arr_obj, val, bret))) { \
LOG_WARN("array contains failed", K(ret)); \
@ -259,6 +262,9 @@ int ObExprArrayContains::eval_array_contains_array(const ObExpr &expr, ObEvalCtx
if (OB_FAIL(ObArrayExprUtils::get_array_obj( \
tmp_allocator, ctx, meta_id, src_array.at(j)->get_string(), arr_obj))) { \
LOG_WARN("construct array obj failed", K(ret)); \
} else if (val_array.at(j)->is_null()) { \
bool contains_null = arr_obj->contain_null(); \
res_datum.at(j)->set_bool(contains_null); \
} else if (FALSE_IT(val = val_array.at(j)->GET_FUNC())) { \
} else if (OB_FAIL(ObArrayUtil::contains(*arr_obj, val, bret))) { \
LOG_WARN("array contains failed", K(ret)); \
@ -455,8 +461,22 @@ int ObExprArrayContains::cg_expr(ObExprCGCtx &expr_cg_ctx,
rt_expr.may_not_need_raw_check_ = false;
rt_expr.extra_ = raw_expr.get_extra();
uint32_t p1 = rt_expr.extra_ == 1 ? 0 : 1;
uint32_t p0 = rt_expr.extra_ == 1 ? 1 : 0;
const ObObjType right_type = rt_expr.args_[p1]->datum_meta_.type_;
const ObObjTypeClass right_tc = ob_obj_type_class(right_type);
ObObjTypeClass right_tc = ob_obj_type_class(right_type);
if (right_tc == ObNullTC) {
// use array element type
ObExecContext *exec_ctx = expr_cg_ctx.session_->get_cur_exec_ctx();
const uint16_t sub_id = rt_expr.args_[p0]->obj_meta_.get_subschema_id();
ObObjType elem_type;
uint32_t unused;
bool is_vec = false;
if (OB_FAIL(ObArrayExprUtils::get_array_element_type(exec_ctx, sub_id, elem_type, unused, is_vec))) {
LOG_WARN("failed to get collection elem type", K(ret), K(sub_id));
} else {
right_tc = ob_obj_type_class(elem_type);
}
}
switch (right_tc) {
case ObIntTC:
rt_expr.eval_func_ = eval_array_contains_int64_t;

View File

@ -271,6 +271,13 @@ int ObExprVectorDims::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_exp
{
int ret = OB_SUCCESS;
rt_expr.eval_func_ = ObExprVectorDims::calc_dims;
if (rt_expr.arg_cnt_ != 1 || OB_ISNULL(rt_expr.args_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("count of children is not 1 or children is null", K(ret), K(rt_expr.arg_cnt_), K(rt_expr.args_));
} else if (rt_expr.args_[0]->type_ == T_FUN_SYS_CAST) {
// return error if cast failed
rt_expr.args_[0]->extra_ &= ~CM_WARN_ON_FAIL;
}
return ret;
}
@ -305,6 +312,13 @@ int ObExprVectorNorm::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_exp
{
int ret = OB_SUCCESS;
rt_expr.eval_func_ = ObExprVectorNorm::calc_norm;
if (rt_expr.arg_cnt_ != 1 || OB_ISNULL(rt_expr.args_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("count of children is not 1 or children is null", K(ret), K(rt_expr.arg_cnt_), K(rt_expr.args_));
} else if (rt_expr.args_[0]->type_ == T_FUN_SYS_CAST) {
// return error if cast failed
rt_expr.args_[0]->extra_ &= ~CM_WARN_ON_FAIL;
}
return ret;
}