From eec9c0a530db55c6c32af6ba5241e8be4b19700e Mon Sep 17 00:00:00 2001 From: obdev Date: Wed, 18 Sep 2024 05:59:46 +0000 Subject: [PATCH] [ARRAY] fix arr column conv cast --- src/sql/engine/basic/ob_expr_values_op.cpp | 2 ++ src/sql/engine/expr/ob_array_cast.cpp | 19 ++++++++-------- src/sql/engine/expr/ob_array_cast.h | 13 ++++++----- src/sql/engine/expr/ob_datum_cast.cpp | 2 +- .../engine/expr/ob_expr_array_contains.cpp | 22 ++++++++++++++++++- src/sql/engine/expr/ob_expr_vector.cpp | 14 ++++++++++++ 6 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/sql/engine/basic/ob_expr_values_op.cpp b/src/sql/engine/basic/ob_expr_values_op.cpp index cf3fabb5a..8ef55bb2e 100644 --- a/src/sql/engine/basic/ob_expr_values_op.cpp +++ b/src/sql/engine/basic/ob_expr_values_op.cpp @@ -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_); } diff --git a/src/sql/engine/expr/ob_array_cast.cpp b/src/sql/engine/expr/ob_array_cast.cpp index 8dbdc5867..39410d338 100644 --- a/src/sql/engine/expr/ob_array_cast.cpp +++ b/src/sql/engine/expr/ob_array_cast.cpp @@ -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(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(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(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(elem_type); diff --git a/src/sql/engine/expr/ob_array_cast.h b/src/sql/engine/expr/ob_array_cast.h index 07c09d6e5..27e348a13 100644 --- a/src/sql/engine/expr/ob_array_cast.h +++ b/src/sql/engine/expr/ob_array_cast.h @@ -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); }; diff --git a/src/sql/engine/expr/ob_datum_cast.cpp b/src/sql/engine/expr/ob_datum_cast.cpp index 49b6a4618..51b3d582c 100644 --- a/src/sql/engine/expr/ob_datum_cast.cpp +++ b/src/sql/engine/expr/ob_datum_cast.cpp @@ -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(); diff --git a/src/sql/engine/expr/ob_expr_array_contains.cpp b/src/sql/engine/expr/ob_expr_array_contains.cpp index 7e070663a..f81ba7994 100644 --- a/src/sql/engine/expr/ob_expr_array_contains.cpp +++ b/src/sql/engine/expr/ob_expr_array_contains.cpp @@ -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; diff --git a/src/sql/engine/expr/ob_expr_vector.cpp b/src/sql/engine/expr/ob_expr_vector.cpp index 30db6958e..97c668129 100644 --- a/src/sql/engine/expr/ob_expr_vector.cpp +++ b/src/sql/engine/expr/ob_expr_vector.cpp @@ -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; }