[ARRAY] array_contains && attrs expr bugfix

This commit is contained in:
obdev
2024-09-18 07:19:30 +00:00
committed by ob-robot
parent f1430fe446
commit 850479a759
3 changed files with 114 additions and 77 deletions

View File

@ -92,7 +92,7 @@ int ObExprArrayContains::calc_result_type2(ObExprResType &type,
if (elem_type->type_id_ == ObNestedType::OB_BASIC_TYPE) {
if (ob_obj_type_class(type2_ptr->get_type()) != static_cast<ObCollectionBasicType *>(elem_type)->basic_meta_.get_type_class()) {
ObObjType calc_type = type2_ptr->get_type();
if (type2_ptr->get_type() == ObDecimalIntType) {
if (type2_ptr->get_type() == ObDecimalIntType || type2_ptr->get_type() == ObNumberType || type2_ptr->get_type() == ObUNumberType) {
calc_type = ObDoubleType;
if (get_decimalint_type(type2_ptr->get_precision()) == DECIMAL_INT_32) {
calc_type = ObFloatType;
@ -180,6 +180,8 @@ int ObExprArrayContains::calc_result_type2(ObExprResType &type,
LOG_WARN("failed to eval args", K(ret)); \
} else if (OB_FAIL(expr.args_[p1]->eval(ctx, datum_val))) { \
LOG_WARN("failed to eval args", K(ret)); \
} else if (datum->is_null()) { \
res.set_null(); \
} 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()) { \
@ -217,6 +219,8 @@ int ObExprArrayContains::eval_array_contains_array(const ObExpr &expr, ObEvalCtx
LOG_WARN("failed to eval args", K(ret));
} else if (OB_FAIL(expr.args_[p1]->eval(ctx, datum_val))) {
LOG_WARN("failed to eval args", K(ret));
} else if (datum->is_null()) {
res.set_null();
} else if (OB_FAIL(ObArrayExprUtils::get_array_obj(tmp_allocator, ctx, l_meta_id, datum->get_string(), arr_obj))) {
LOG_WARN("construct array obj failed", K(ret));
} else if (datum_val->is_null()) {
@ -232,48 +236,50 @@ int ObExprArrayContains::eval_array_contains_array(const ObExpr &expr, ObEvalCtx
return ret;
}
#define EVAL_FUNC_ARRAY_CONTAINS_BATCH(TYPE, GET_FUNC) \
int ObExprArrayContains::eval_array_contains_batch_##TYPE( \
const ObExpr &expr, ObEvalCtx &ctx, const ObBitVector &skip, const int64_t batch_size) \
{ \
int ret = OB_SUCCESS; \
ObDatumVector res_datum = expr.locate_expr_datumvector(ctx); \
ObBitVector &eval_flags = expr.get_evaluated_flags(ctx); \
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx); \
common::ObArenaAllocator &tmp_allocator = tmp_alloc_g.get_allocator(); \
uint32_t p0 = expr.extra_ == 1 ? 1 : 0; \
uint32_t p1 = expr.extra_ == 1 ? 0 : 1; \
const uint16_t meta_id = expr.args_[p0]->obj_meta_.get_subschema_id(); \
ObIArrayType *arr_obj = NULL; \
if (OB_FAIL(expr.args_[p0]->eval_batch(ctx, skip, batch_size))) { \
LOG_WARN("eval date_unit_datum failed", K(ret)); \
} else if (OB_FAIL(expr.args_[p1]->eval_batch(ctx, skip, batch_size))) { \
LOG_WARN("failed to eval batch result args0", K(ret)); \
} else { \
ObDatumVector src_array = expr.args_[p0]->locate_expr_datumvector(ctx); \
ObDatumVector val_array = expr.args_[p1]->locate_expr_datumvector(ctx); \
for (int64_t j = 0; OB_SUCC(ret) && j < batch_size; ++j) { \
if (skip.at(j) || eval_flags.at(j)) { \
continue; \
} \
eval_flags.set(j); \
bool bret = false; \
TYPE val; \
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)); \
} else { \
res_datum.at(j)->set_bool(bret); \
} \
} \
} \
return ret; \
#define EVAL_FUNC_ARRAY_CONTAINS_BATCH(TYPE, GET_FUNC) \
int ObExprArrayContains::eval_array_contains_batch_##TYPE( \
const ObExpr &expr, ObEvalCtx &ctx, const ObBitVector &skip, const int64_t batch_size) \
{ \
int ret = OB_SUCCESS; \
ObDatumVector res_datum = expr.locate_expr_datumvector(ctx); \
ObBitVector &eval_flags = expr.get_evaluated_flags(ctx); \
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx); \
common::ObArenaAllocator &tmp_allocator = tmp_alloc_g.get_allocator(); \
uint32_t p0 = expr.extra_ == 1 ? 1 : 0; \
uint32_t p1 = expr.extra_ == 1 ? 0 : 1; \
const uint16_t meta_id = expr.args_[p0]->obj_meta_.get_subschema_id(); \
ObIArrayType *arr_obj = NULL; \
if (OB_FAIL(expr.args_[p0]->eval_batch(ctx, skip, batch_size))) { \
LOG_WARN("eval date_unit_datum failed", K(ret)); \
} else if (OB_FAIL(expr.args_[p1]->eval_batch(ctx, skip, batch_size))) { \
LOG_WARN("failed to eval batch result args0", K(ret)); \
} else { \
ObDatumVector src_array = expr.args_[p0]->locate_expr_datumvector(ctx); \
ObDatumVector val_array = expr.args_[p1]->locate_expr_datumvector(ctx); \
for (int64_t j = 0; OB_SUCC(ret) && j < batch_size; ++j) { \
if (skip.at(j) || eval_flags.at(j)) { \
continue; \
} \
eval_flags.set(j); \
bool bret = false; \
TYPE val; \
if (src_array.at(j)->is_null()) { \
res_datum.at(j)->set_null(); \
} else 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)); \
} else { \
res_datum.at(j)->set_bool(bret); \
} \
} \
} \
return ret; \
}
EVAL_FUNC_ARRAY_CONTAINS_BATCH(int64_t, get_int)
@ -307,7 +313,9 @@ int ObExprArrayContains::eval_array_contains_array_batch(const ObExpr &expr, ObE
}
eval_flags.set(j);
bool bret = false;
if (OB_FAIL(
if (src_array.at(j)->is_null()) {
res_datum.at(j)->set_null();
} else if (OB_FAIL(
ObArrayExprUtils::get_array_obj(tmp_allocator, ctx, l_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()) {
@ -348,8 +356,11 @@ int ObExprArrayContains::eval_array_contains_array_batch(const ObExpr &expr, ObE
ObIArrayType *arr_obj = NULL; \
TYPE val; \
for (int64_t idx = bound.start(); OB_SUCC(ret) && idx < bound.end(); ++idx) { \
bool is_null_res = false; \
if (skip.at(idx) || eval_flags.at(idx)) { \
continue; \
} else if (left_vec->is_null(idx)) { \
is_null_res = true; \
} else if (left_format == VEC_UNIFORM || left_format == VEC_UNIFORM_CONST) { \
ObString left = left_vec->get_string(idx); \
if (OB_FAIL(ObNestedVectorFunc::construct_param(tmp_allocator, ctx, meta_id, left, arr_obj))) { \
@ -361,6 +372,9 @@ int ObExprArrayContains::eval_array_contains_array_batch(const ObExpr &expr, ObE
} \
bool bret = false; \
if (OB_FAIL(ret)) { \
} else if (is_null_res) { \
res_vec->set_null(idx); \
eval_flags.set(idx); \
} else if (right_vec->is_null(idx)) { \
bool contains_null = arr_obj->contain_null(); \
res_vec->set_bool(idx, contains_null); \
@ -404,8 +418,11 @@ int ObExprArrayContains::eval_array_contains_array_vector(const ObExpr &expr, Ob
ObIArrayType *arr_obj = NULL;
ObIArrayType *arr_val = NULL;
for (int64_t idx = bound.start(); OB_SUCC(ret) && idx < bound.end(); ++idx) {
bool is_null_res = false;
if (skip.at(idx) || eval_flags.at(idx)) {
continue;
} else if (left_vec->is_null(idx)) {
is_null_res = true;
} else if (left_format == VEC_UNIFORM || left_format == VEC_UNIFORM_CONST) {
ObString left = left_vec->get_string(idx);
if (OB_FAIL(ObNestedVectorFunc::construct_param(tmp_allocator, ctx, left_meta_id, left, arr_obj))) {
@ -416,6 +433,9 @@ int ObExprArrayContains::eval_array_contains_array_vector(const ObExpr &expr, Ob
LOG_WARN("construct array obj failed", K(ret));
}
if (OB_FAIL(ret)) {
} else if (is_null_res) {
res_vec->set_null(idx);
eval_flags.set(idx);
} else if (right_vec->is_null(idx)) {
bool contains_null = arr_obj->contain_null();
res_vec->set_bool(idx, contains_null);
@ -477,36 +497,38 @@ int ObExprArrayContains::cg_expr(ObExprCGCtx &expr_cg_ctx,
right_tc = ob_obj_type_class(elem_type);
}
}
switch (right_tc) {
case ObIntTC:
rt_expr.eval_func_ = eval_array_contains_int64_t;
rt_expr.eval_batch_func_ = eval_array_contains_batch_int64_t;
rt_expr.eval_vector_func_ = eval_array_contains_vector_int64_t;
break;
case ObFloatTC:
rt_expr.eval_func_ = eval_array_contains_float;
rt_expr.eval_batch_func_ = eval_array_contains_batch_float;
rt_expr.eval_vector_func_ = eval_array_contains_vector_float;
break;
case ObDoubleTC:
rt_expr.eval_func_ = eval_array_contains_double;
rt_expr.eval_batch_func_ = eval_array_contains_batch_double;
rt_expr.eval_vector_func_ = eval_array_contains_vector_double;
break;
case ObStringTC:
rt_expr.eval_func_ = eval_array_contains_ObString;
rt_expr.eval_batch_func_ = eval_array_contains_batch_ObString;
rt_expr.eval_vector_func_ = eval_array_contains_vector_ObString;
break;
case ObNullTC:
case ObCollectionSQLTC:
rt_expr.eval_func_ = eval_array_contains_array;
rt_expr.eval_batch_func_ = eval_array_contains_array_batch;
rt_expr.eval_vector_func_ = eval_array_contains_array_vector;
break;
default :
ret = OB_ERR_INVALID_TYPE_FOR_OP;
LOG_WARN("invalid type", K(ret), K(right_type));
if OB_SUCC(ret) {
switch (right_tc) {
case ObIntTC:
rt_expr.eval_func_ = eval_array_contains_int64_t;
rt_expr.eval_batch_func_ = eval_array_contains_batch_int64_t;
rt_expr.eval_vector_func_ = eval_array_contains_vector_int64_t;
break;
case ObFloatTC:
rt_expr.eval_func_ = eval_array_contains_float;
rt_expr.eval_batch_func_ = eval_array_contains_batch_float;
rt_expr.eval_vector_func_ = eval_array_contains_vector_float;
break;
case ObDoubleTC:
rt_expr.eval_func_ = eval_array_contains_double;
rt_expr.eval_batch_func_ = eval_array_contains_batch_double;
rt_expr.eval_vector_func_ = eval_array_contains_vector_double;
break;
case ObStringTC:
rt_expr.eval_func_ = eval_array_contains_ObString;
rt_expr.eval_batch_func_ = eval_array_contains_batch_ObString;
rt_expr.eval_vector_func_ = eval_array_contains_vector_ObString;
break;
case ObNullTC:
case ObCollectionSQLTC:
rt_expr.eval_func_ = eval_array_contains_array;
rt_expr.eval_batch_func_ = eval_array_contains_array_batch;
rt_expr.eval_vector_func_ = eval_array_contains_array_vector;
break;
default :
ret = OB_ERR_INVALID_TYPE_FOR_OP;
LOG_WARN("invalid type", K(ret), K(right_type));
}
}
}