[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

@ -530,6 +530,36 @@ struct ObFloatDivFunc
}
};
struct ObFloatVectorDivFunc
{
template <typename ResVector, typename LeftVector, typename RightVector>
int operator()(ResVector &res_vec, const LeftVector &l_vec, const RightVector &r_vec,
const int64_t idx, const bool &is_oracle) const
{
int ret = OB_SUCCESS;
const float left_f = l_vec.get_float(idx);
const float right_f = r_vec.get_float(idx);
const float result_f = left_f / right_f;
if (OB_UNLIKELY(ObExprDiv::is_float_out_of_range(result_f))
&& !is_oracle) {
ret = OB_OPERATE_OVERFLOW;
char expr_str[OB_MAX_TWO_OPERATOR_EXPR_LENGTH];
int64_t pos = 0;
databuff_printf(expr_str,
OB_MAX_TWO_OPERATOR_EXPR_LENGTH,
pos,
"'(%e / %e)'",
left_f,
right_f);
LOG_USER_ERROR(OB_OPERATE_OVERFLOW, "BINARY_FLOAT", expr_str);
LOG_WARN("float out of range", K(ret), K(left_f), K(right_f));
} else {
res_vec.set_float(idx, result_f);
LOG_DEBUG("succ to div float", K(left_f), K(right_f), K(result_f));
}
return ret;
}
};
int ObExprDiv::div_float(EVAL_FUNC_ARG_DECL)
{
@ -543,6 +573,13 @@ int ObExprDiv::div_float_batch(BATCH_EVAL_FUNC_ARG_DECL)
return def_batch_arith_op_by_datum_func<ObFloatDivFunc>(BATCH_EVAL_FUNC_ARG_LIST, is_oracle);
}
int ObExprDiv::div_float_vector(VECTOR_EVAL_FUNC_ARG_DECL)
{
const bool is_oracle = lib::is_oracle_mode();
return def_fixed_len_vector_arith_op_func<ObFloatVectorDivFunc>(VECTOR_EVAL_FUNC_ARG_LIST, is_oracle);
}
struct ObDoubleDivFunc
{
int operator()(ObDatum &res, const ObDatum &l, const ObDatum &r,
@ -582,6 +619,47 @@ struct ObDoubleDivFunc
}
};
struct ObDoubleVectorDivFunc
{
template <typename ResVector, typename LeftVector, typename RightVector>
int operator()(ResVector &res_vec, const LeftVector &l_vec, const RightVector &r_vec,
const int64_t idx, const ObExpr &expr, const bool &is_oracle) const
{
int ret = OB_SUCCESS;
const double left_d = l_vec.get_double(idx);
const double right_d = r_vec.get_double(idx);
if (!is_oracle && (fabs(right_d) == 0.0)) {
if (expr.is_error_div_by_zero_) {
ret = OB_DIVISION_BY_ZERO;
} else {
res_vec.set_null(idx);
}
} else {
const double result_d = left_d / right_d;
if (OB_UNLIKELY(ObExprDiv::is_double_out_of_range(result_d))
&& T_OP_AGG_DIV != expr.type_
&& !is_oracle) {
ret = OB_OPERATE_OVERFLOW;
char expr_str[OB_MAX_TWO_OPERATOR_EXPR_LENGTH];
int64_t pos = 0;
databuff_printf(expr_str,
OB_MAX_TWO_OPERATOR_EXPR_LENGTH,
pos,
"'(%e / %e)'",
left_d,
right_d);
LOG_USER_ERROR(OB_OPERATE_OVERFLOW, is_oracle_mode() ? "BINARY_DOUBLE" : "DOUBLE",
expr_str);
LOG_WARN("double out of range", K(ret), "left", left_d, "right", right_d);
} else {
res_vec.set_double(idx, result_d);
}
LOG_DEBUG("succ to div double", K(left_d), K(right_d), K(result_d));
}
return ret;
}
};
int ObExprDiv::div_double(EVAL_FUNC_ARG_DECL)
{
const bool is_oracle = lib::is_oracle_mode();
@ -594,6 +672,13 @@ int ObExprDiv::div_double_batch(BATCH_EVAL_FUNC_ARG_DECL)
return def_batch_arith_op_by_datum_func<ObDoubleDivFunc>(BATCH_EVAL_FUNC_ARG_LIST, expr, is_oracle);
}
int ObExprDiv::div_double_vector(VECTOR_EVAL_FUNC_ARG_DECL)
{
const bool is_oracle = lib::is_oracle_mode();
return def_fixed_len_vector_arith_op_func<ObDoubleVectorDivFunc>(VECTOR_EVAL_FUNC_ARG_LIST, expr,
is_oracle);
}
struct ObNumberDivFunc
{
int operator()(ObDatum &res, const ObDatum &l, const ObDatum &r, const ObExpr &expr,
@ -651,6 +736,59 @@ struct ObNumberDivFunc
}
};
struct ObNumberVectorDivFunc
{
template <typename ResVector, typename LeftVector, typename RightVector>
int operator()(ResVector &res_vec, const LeftVector &l_vec, const RightVector &r_vec,
const int64_t idx, const ObExpr &expr, ObEvalCtx &ctx, const bool &is_oracle) const
{
int ret = OB_SUCCESS;
if (r_vec.get_number(idx).is_zero()) {
if (is_oracle) {
ret = OB_ERR_DIVISOR_IS_ZERO;
LOG_WARN("divisor is equal to zero on oracle mode", K(ret));
} else if (expr.is_error_div_by_zero_) {
ret = OB_DIVISION_BY_ZERO;
} else {
res_vec.set_null(idx);
LOG_DEBUG("divisor is equal to zero", K(idx), K(ret));
}
} else {
number::ObNumber lnum(l_vec.get_number(idx));
number::ObNumber rnum(r_vec.get_number(idx));
char local_buff[ObNumber::MAX_BYTE_LEN];
ObDataBuffer local_alloc(local_buff, ObNumber::MAX_BYTE_LEN);
ObNumber result_num;
if (OB_FAIL(lnum.div_v3(rnum, result_num, local_alloc))) {
LOG_WARN("add number failed", K(ret));
} else {
if (is_oracle) {
res_vec.set_number(idx, result_num);
} else {
int64_t div_pi = 0;
if (OB_FAIL(ctx.exec_ctx_.get_my_session()->get_div_precision_increment(div_pi))) {
LOG_WARN("get_div_precision_increment failed", K(ret));
} else {
const int64_t calc_scale = expr.div_calc_scale_;
if (calc_scale > 0 && OB_FAIL(result_num.trunc(calc_scale))) {
//calc_scale is calc_scale ,not res_scale.
//trunc with calc_scale and round with res_scale
LOG_WARN("failed to trunc result number", K(ret), K(result_num), K(calc_scale));
} else {
res_vec.set_number(idx, result_num);
}
LOG_DEBUG("finish div", K(ret), K(calc_scale),
/*K(scale1), K(scale2), K(new_scale1), K(new_scale2),*/
K(div_pi), K(result_num), K(lnum), K(rnum));
}
}
}
}
return ret;
}
};
int ObExprDiv::div_number(EVAL_FUNC_ARG_DECL)
{
const bool is_oracle = lib::is_oracle_mode();
@ -663,6 +801,14 @@ int ObExprDiv::div_number_batch(BATCH_EVAL_FUNC_ARG_DECL)
return def_batch_arith_op_by_datum_func<ObNumberDivFunc>(BATCH_EVAL_FUNC_ARG_LIST, expr, ctx, is_oracle);
}
int ObExprDiv::div_number_vector(VECTOR_EVAL_FUNC_ARG_DECL)
{
const bool is_oracle = lib::is_oracle_mode();
return def_variable_len_vector_arith_op_func<ObNumberVectorDivFunc>(VECTOR_EVAL_FUNC_ARG_LIST, expr, ctx,
is_oracle);
}
struct ObIntervalYMNumberDivFunc
{
int operator()(ObDatum &res, const ObDatum &l, const ObDatum &r) const
@ -1072,20 +1218,24 @@ int ObExprDiv::cg_expr(ObExprCGCtx &op_cg_ctx,
OB_ASSERT(right == input_types_[1].get_calc_type());
rt_expr.inner_functions_ = NULL;
rt_expr.may_not_need_raw_check_ = false;
LOG_DEBUG("arrive here cg_expr", K(ret), K(raw_expr), K(rt_expr));
rt_expr.div_calc_scale_ = raw_expr.get_result_type().get_calc_scale();
switch (rt_expr.datum_meta_.type_) {
case ObFloatType: {
SET_DIV_FUNC_PTR(div_float);
rt_expr.eval_vector_func_ = div_float_vector;
break;
}
case ObDoubleType: {
SET_DIV_FUNC_PTR(div_double);
rt_expr.eval_vector_func_ = div_double_vector;
break;
}
case ObUNumberType:
case ObNumberType: {
SET_DIV_FUNC_PTR(div_number);
rt_expr.eval_vector_func_ = div_number_vector;
break;
}
case ObIntervalYMType: {