Vectorization 2.0, short-circuit processing of ‘in’ expressions.

This commit is contained in:
qingsuijiu
2024-01-22 07:47:56 +00:00
committed by ob-robot
parent 05b1bc313b
commit 06d00daec0

View File

@ -1087,6 +1087,21 @@ int ObExprInOrNotIn::inner_eval_vector_in_without_row_fallback(const ObExpr &exp
ObDatum *right_store[expr.inner_func_cnt_]; // store all right param ptrs
ObBitVector &eval_flags = expr.get_evaluated_flags(ctx);
bool right_has_null = false; // right param has null
ObBitVector &my_skip = expr.get_pvt_skip(ctx);
my_skip.deep_copy(skip, bound.start(), bound.end());
bool left_all_null = true;
for (int64_t idx = bound.start(); idx < bound.end(); ++idx) {
if (input_left_vec->is_null(idx)) {
my_skip.set(idx);
res_vec->set_null(idx);
eval_flags.set(idx);
} else {
left_all_null = false;
}
}
// If all the values on the left are null,
// perform a short-circuit calculation and return immediately.
if (!left_all_null) {
/*
* CAN_CMP_MEM used for common short path
* the params of left and right
@ -1124,9 +1139,8 @@ int ObExprInOrNotIn::inner_eval_vector_in_without_row_fallback(const ObExpr &exp
int32_t left_str_len = 0;
for (; OB_SUCC(ret) && idx < bound.end(); ++idx) {
// If can_cmp_mem is true, then it is guaranteed that the right side is non-null.
if (input_left_vec->is_null(idx)) {
res_vec->set_null(idx);
} else {
// If input_left_vec->is_null(idx), res_vec has been set before.
if (!input_left_vec->is_null(idx)) {
input_left_vec->get_payload(idx, left_str_ptr, left_str_len);
if (left_str_len > 0 && SPACE == left_str_ptr[left_str_len - 1]) {
can_cmp_mem = false;
@ -1160,13 +1174,10 @@ int ObExprInOrNotIn::inner_eval_vector_in_without_row_fallback(const ObExpr &exp
l_len = (reinterpret_cast<ObFixedLengthBase *>(input_left_vec))->get_length();
}
for (; OB_SUCC(ret) && idx < bound.end(); ++idx) {
if (skip.at(idx) || eval_flags.at(idx)) {
if (my_skip.at(idx) || eval_flags.at(idx)) {
continue;
}
if (input_left_vec->is_null(idx)) {
res_vec->set_null(idx);
eval_flags.set(idx);
} else {
// The situation "input_left_vec->is_null(idx)" has already been handled previously.
if (std::is_same<LeftVec, ObFixedLengthBase>::value) {
l_payload = fixed_base_l_payload + l_len * idx;
} else {
@ -1688,6 +1699,19 @@ int ObExprInOrNotIn::inner_eval_vector_in_without_row(const ObExpr &expr,
const char *fixed_base_l_payload = nullptr;
bool is_exist = false;
bool right_all_null = false;
ObBitVector &my_skip = expr.get_pvt_skip(ctx);
my_skip.deep_copy(skip, bound.start(), bound.end());
bool left_all_null = true;
for (int64_t idx = bound.start(); idx < bound.end(); ++idx) {
if (input_left_vec->is_null(idx)) {
my_skip.set(idx);
res_vec->set_null(idx);
eval_flags.set(idx);
} else {
left_all_null = false;
}
}
if (!left_all_null) {
if (OB_FAIL(build_right_hash_without_row(in_id, right_param_num, expr,
ctx, exec_ctx, in_ctx, right_has_null))) {
LOG_WARN("failed to build hash table for right params", K(ret));
@ -1741,10 +1765,8 @@ int ObExprInOrNotIn::inner_eval_vector_in_without_row(const ObExpr &expr,
if (skip.at(left_idx) || eval_flags.at(left_idx)) {
continue;
}
if (input_left_vec->is_null(left_idx)) {
res_vec->set_null(left_idx);
eval_flags.set(left_idx);
} else if (OB_NOT_NULL(in_ctx)) { //second we search in hashset.
// The situation "input_left_vec->is_null(idx)" has already been handled previously.
if (OB_NOT_NULL(in_ctx)) { //second we search in hashset.
if (std::is_same<LeftVec, ObFixedLengthBase>::value) {
left_datum.ptr_ = fixed_base_l_payload + left_idx * left_datum.len_;
} else {
@ -1764,6 +1786,7 @@ int ObExprInOrNotIn::inner_eval_vector_in_without_row(const ObExpr &expr,
} else {
ret = eval_vector_in_without_row_fallback(expr, ctx, skip, bound);
}
}
return ret;
}