[FEAT MERGE] impl vectorization 2.0

Co-authored-by: Naynahs <cfzy002@126.com>
Co-authored-by: hwx65 <1780011298@qq.com>
Co-authored-by: oceanoverflow <oceanoverflow@gmail.com>
This commit is contained in:
obdev
2023-12-22 03:43:19 +00:00
committed by ob-robot
parent 1178245448
commit b6773084c6
592 changed files with 358124 additions and 303288 deletions

View File

@ -17,6 +17,7 @@
#include "sql/engine/expr/ob_expr_less_equal.h"
#include "sql/engine/expr/ob_expr_cmp_func.h"
#include "sql/session/ob_sql_session_info.h"
#include "share/vector/expr_cmp_func.h"
namespace oceanbase
{
@ -77,6 +78,119 @@ int calc_between_expr(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res_datum)
return ret;
}
// eval_left_and_right_operand
template <typename ValVec, typename ResVec>
static int eval_lr_operand(const ObExpr &expr, ObEvalCtx &ctx,
ObBitVector &skip, const EvalBound &bound)
{
int ret = OB_SUCCESS;
const ObExpr &val_expr = *expr.args_[0];
const ObExpr &left_expr = *expr.args_[1];
const ObExpr &right_expr = *expr.args_[2];
ValVec *val_vec = static_cast<ValVec *>(val_expr.get_vector(ctx));
ResVec *res_vec = static_cast<ResVec *>(expr.get_vector(ctx));
if (val_vec->has_null()) {
for (int i = bound.start(); i < bound.end(); ++i) {
if (!skip.at(i) && val_vec->is_null(i)) {
res_vec->set_null(i);
skip.set(i);
}
}
}
// if skip is all true, `eval_vector` still needs to be called, for that expr format may not be inited.
if (OB_FAIL(left_expr.eval_vector(ctx, skip, bound))) {
LOG_WARN("eval left operand failed", K(ret));
} else if (OB_FAIL(right_expr.eval_vector(ctx, skip, bound))) {
LOG_WARN("eval right operand failed", K(ret));
}
return ret;
}
template <typename ValVec>
static int dispatch_eval_between_operands(const ObExpr &expr, ObEvalCtx &ctx,
ObBitVector &skip, const EvalBound &bound)
{
int ret = OB_SUCCESS;
VectorFormat res_format = expr.get_format(ctx);
switch (res_format) {
case VEC_FIXED: {
ret = eval_lr_operand<ValVec, ObBitmapNullVectorBase>(expr, ctx, skip, bound);
break;
}
case VEC_UNIFORM: {
ret = eval_lr_operand<ValVec, ObUniformFormat<false>>(expr, ctx, skip, bound);
break;
}
case VEC_UNIFORM_CONST: {
ret = eval_lr_operand<ValVec, ObUniformFormat<true>>(expr, ctx, skip, bound);
break;
}
default: {
ret = eval_lr_operand<ValVec, ObVectorBase>(expr, ctx, skip, bound);
}
}
return ret;
}
static int eval_between_operands(const ObExpr &expr, ObEvalCtx &ctx,
ObBitVector &skip, const EvalBound &bound)
{
int ret = OB_SUCCESS;
const ObExpr &val_expr = *expr.args_[0];
if (OB_FAIL(val_expr.eval_vector(ctx, skip, bound))) {
LOG_WARN("eval left operand failed", K(ret));
} else {
VectorFormat val_format = val_expr.get_format(ctx);
switch (val_format) {
case VEC_DISCRETE:
case VEC_CONTINUOUS:
case VEC_FIXED: {
ret = dispatch_eval_between_operands<ObBitmapNullVectorBase>(expr, ctx, skip, bound);
break;
}
case VEC_UNIFORM: {
ret = dispatch_eval_between_operands<ObUniformFormat<false>>(expr, ctx, skip, bound);
break;
}
case VEC_UNIFORM_CONST: {
ret = dispatch_eval_between_operands<ObUniformFormat<true>>(expr, ctx, skip, bound);
break;
}
default: {
ret = dispatch_eval_between_operands<ObVectorBase>(expr, ctx, skip, bound);
}
}
}
return ret;
}
int ObExprBetween::eval_between_vector(const ObExpr &expr,
ObEvalCtx &ctx,
const ObBitVector &skip,
const EvalBound &bound)
{
// left <= val <= right
int ret = OB_SUCCESS;
const ObExpr &val_expr = *expr.args_[0];
const ObExpr &left_expr = *expr.args_[1];
const ObExpr &right_expr = *expr.args_[2];
ObBitVector &my_skip = expr.get_pvt_skip(ctx);
my_skip.deep_copy(skip, bound.start(), bound.end());
if (OB_FAIL(eval_between_operands(expr, ctx, my_skip, bound))) {
LOG_WARN("eval between operands failed", K(ret));
} else if (OB_FAIL((reinterpret_cast<EvalVectorBetweenFunc>(expr.inner_functions_[2]))(
expr, left_expr, val_expr, ctx, my_skip, bound))) { // eval left <= val
LOG_WARN("compare left and val failed", K(ret));
} else if (OB_FAIL((reinterpret_cast<EvalVectorBetweenFunc>(expr.inner_functions_[3]))(
expr, val_expr, right_expr, ctx, my_skip, bound))) { // eval val <= right
LOG_WARN("compare val and right failed", K(ret));
} else {
ObBitVector &eval_flags = expr.get_evaluated_flags(ctx);
eval_flags.bit_not(skip, bound);
}
return ret;
}
int ObExprBetween::cg_expr(ObExprCGCtx &expr_cg_ctx,
const ObRawExpr &raw_expr,
ObExpr &rt_expr) const
@ -92,6 +206,8 @@ int ObExprBetween::cg_expr(ObExprCGCtx &expr_cg_ctx,
} else {
DatumCmpFunc cmp_func_1 = NULL; // left <= val
DatumCmpFunc cmp_func_2 = NULL; // val <= right
EvalVectorBetweenFunc vec_cmp_func_1 = NULL; // left <= val
EvalVectorBetweenFunc vec_cmp_func_2 = NULL; // val <= right
const ObDatumMeta &val_meta = rt_expr.args_[0]->datum_meta_;
const ObDatumMeta &left_meta = rt_expr.args_[1]->datum_meta_;
const ObDatumMeta &right_meta = rt_expr.args_[2]->datum_meta_;
@ -121,15 +237,33 @@ int ObExprBetween::cg_expr(ObExprCGCtx &expr_cg_ctx,
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get_datum_expr_cmp_func failed", K(ret), K(val_meta), K(right_meta),
K(is_oracle_mode()), K(rt_expr));
} else if (OB_ISNULL(vec_cmp_func_1 = VectorCmpExprFuncsHelper::get_eval_vector_between_expr_cmp_func(
left_meta, val_meta, EvalBetweenStage::BETWEEN_LEFT))) {
ret = OB_ERR_UNEXPECTED;
VecValueTypeClass value_tc = get_vec_value_tc(val_meta.type_, val_meta.scale_, val_meta.precision_);
VecValueTypeClass left_tc = get_vec_value_tc(left_meta.type_, left_meta.scale_, left_meta.precision_);
LOG_WARN("The result of get_eval_vector_between_expr_cmp_func(left) is null.",
K(ret), K(left_meta), K(val_meta), K(right_meta), K(value_tc), K(left_tc), K(rt_expr));
} else if (OB_ISNULL(vec_cmp_func_2 = VectorCmpExprFuncsHelper::get_eval_vector_between_expr_cmp_func(
val_meta, right_meta, EvalBetweenStage::BETWEEN_RIGHT))) {
ret = OB_ERR_UNEXPECTED;
VecValueTypeClass value_tc = get_vec_value_tc(val_meta.type_, val_meta.scale_, val_meta.precision_);
VecValueTypeClass right_tc = get_vec_value_tc(right_meta.type_, right_meta.scale_, right_meta.precision_);
LOG_WARN("The result of get_eval_vector_between_expr_cmp_func(right) is null.",
K(ret), K(left_meta), K(val_meta), K(right_meta), K(value_tc), K(right_tc), K(rt_expr));
} else if (OB_ISNULL(rt_expr.inner_functions_ = reinterpret_cast<void**>(
expr_cg_ctx.allocator_->alloc(sizeof(DatumCmpFunc) * 2)))) {
expr_cg_ctx.allocator_->alloc(sizeof(DatumCmpFunc) * 2 +
sizeof(EvalVectorBetweenFunc) * 2)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("alloc memory for inner_functions_ failed", K(ret));
} else {
rt_expr.inner_func_cnt_ = 2;
rt_expr.inner_func_cnt_ = 4;
rt_expr.inner_functions_[0] = reinterpret_cast<void*>(cmp_func_1);
rt_expr.inner_functions_[1] = reinterpret_cast<void*>(cmp_func_2);
rt_expr.inner_functions_[2] = reinterpret_cast<void*>(vec_cmp_func_1);
rt_expr.inner_functions_[3] = reinterpret_cast<void*>(vec_cmp_func_2);
rt_expr.eval_func_ = calc_between_expr;
rt_expr.eval_vector_func_ = eval_between_vector;
}
}
return ret;