patch 4.0

This commit is contained in:
wangzelin.wzl
2022-10-24 10:34:53 +08:00
parent 4ad6e00ec3
commit 93a1074b0c
10533 changed files with 2588271 additions and 2299373 deletions

View File

@ -16,36 +16,39 @@
#include "sql/engine/user_defined_function/ob_user_defined_function.h"
#include "sql/engine/expr/ob_sql_expression.h"
#include "sql/engine/ob_exec_context.h"
#include "sql/code_generator/ob_static_engine_expr_cg.h"
namespace oceanbase {
namespace oceanbase
{
using namespace common;
namespace sql {
namespace sql
{
ObExprDllUdf::ObExprDllUdf(ObIAllocator& alloc)
: ObFuncExprOperator(alloc, T_FUN_NORMAL_UDF, N_NORMAL_UDF, PARAM_NUM_UNKNOWN, NOT_ROW_DIMENSION),
allocator_(alloc),
udf_func_(),
udf_ctx_(),
udf_meta_(),
udf_attributes_(),
udf_attributes_types_(),
calculable_results_(),
sql_expression_factory_(allocator_),
expr_op_factory_(allocator_)
{}
ObExprDllUdf::ObExprDllUdf(ObIAllocator &alloc) :
ObFuncExprOperator(alloc, T_FUN_NORMAL_UDF, N_NORMAL_UDF, PARAM_NUM_UNKNOWN, NOT_ROW_DIMENSION, INTERNAL_IN_MYSQL_MODE),
allocator_(alloc),
udf_func_(),
udf_meta_(),
udf_attributes_(),
udf_attributes_types_(),
calculable_results_(),
sql_expression_factory_(allocator_),
expr_op_factory_(allocator_)
{
}
ObExprDllUdf::ObExprDllUdf(ObIAllocator& alloc, ObExprOperatorType type, const char* name)
: ObFuncExprOperator(alloc, type, name, PARAM_NUM_UNKNOWN, NOT_ROW_DIMENSION),
allocator_(alloc),
udf_func_(),
udf_ctx_(),
udf_meta_(),
udf_attributes_(),
udf_attributes_types_(),
calculable_results_(),
sql_expression_factory_(allocator_),
expr_op_factory_(allocator_)
{}
ObExprDllUdf::ObExprDllUdf(ObIAllocator &alloc, ObExprOperatorType type, const char *name) :
ObFuncExprOperator(alloc, type, name, PARAM_NUM_UNKNOWN, NOT_ROW_DIMENSION),
allocator_(alloc),
udf_func_(),
udf_meta_(),
udf_attributes_(),
udf_attributes_types_(),
calculable_results_(),
sql_expression_factory_(allocator_),
expr_op_factory_(allocator_)
{
}
ObExprDllUdf::~ObExprDllUdf()
{
@ -54,129 +57,96 @@ ObExprDllUdf::~ObExprDllUdf()
}
/*
* ret of UDF can only be three types, including: STRING, DOUBLE and LONG LONG.
* input of UDF can be any type.
* such as select udf_sum(t1.c1) from t1
* UDF的结果是强制性的,UDF的ret仅仅只有三种类型,分别是STRINGDOUBLELONG LONG
* 这里不存类型的推导。
* UDF的输入则是可以是任何类型,
* 比如select udf_sum(t1.c1) from t1
* select udf_sum(t2.c1) from t2
* t1.c1 is varchar, t2.c1 is int
* t1.c1varchart2.c1是int,只要udf_sum的执行函数里面写清楚执行逻辑即可。
* */
int ObExprDllUdf::calc_result_typeN(
ObExprResType& type, ObExprResType* types, int64_t param_num, ObExprTypeCtx& type_ctx) const
int ObExprDllUdf::calc_result_typeN(ObExprResType &type,
ObExprResType *types,
int64_t param_num,
ObExprTypeCtx &type_ctx) const
{
int ret = OB_SUCCESS;
/* the result type of udf is defined by user, no matter what the inputs' type or count. */
UNUSED(param_num);
UNUSED(types);
UNUSED(type_ctx);
if (OB_FAIL(ObUdfUtil::calc_udf_result_type(
allocator_, &udf_func_, udf_meta_, udf_attributes_, udf_attributes_types_, type))) {
allocator_, &udf_func_, udf_meta_,
udf_attributes_, udf_attributes_types_,
type, types, param_num, type_ctx))) {
LOG_WARN("failed to cale udf result type");
}
return ret;
}
int ObExprDllUdf::calc_resultN(ObObj& result, const ObObj* objs_stack, int64_t param_num, ObExprCtx& expr_ctx) const
{
int ret = OB_SUCCESS;
ObUdfFunction::ObUdfCtx* udf_ctx = nullptr;
ObNormalUdfExeUnit* udf_exec_unit = nullptr;
ObUdfCtxMgr* udf_ctx_mgr = nullptr;
if (OB_ISNULL(expr_ctx.calc_buf_) || OB_ISNULL(expr_ctx.exec_ctx_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("the calc buf is null", K(ret), K(expr_ctx.calc_buf_), K(expr_ctx.exec_ctx_), K(lbt()));
} else if (OB_FAIL(expr_ctx.exec_ctx_->get_udf_ctx_mgr(udf_ctx_mgr))) {
LOG_WARN("Failed to get udf ctx map", K(ret));
} else if (OB_FAIL(udf_ctx_mgr->get_udf_ctx(get_id(), udf_exec_unit))) {
if (ret == OB_HASH_NOT_EXIST) {
if (OB_FAIL(udf_ctx_mgr->register_udf_expr(this, &udf_func_, udf_exec_unit))) {
LOG_WARN("failed to register this op to udf ctx mgr", K(ret));
} else if (OB_ISNULL(udf_exec_unit) || OB_ISNULL(udf_exec_unit->udf_ctx_)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("the udf ctx is null", K(ret));
} else if (FALSE_IT(udf_ctx = udf_exec_unit->udf_ctx_)) {
} else if (OB_FAIL(ObUdfUtil::init_udf_args(
udf_ctx_mgr->get_allocator(), udf_attributes_, udf_attributes_types_, udf_ctx->udf_args_))) {
LOG_WARN("failed to set udf args", K(ret));
} else if (OB_FAIL(ObUdfUtil::init_const_args(
udf_ctx_mgr->get_allocator(), calculable_results_, udf_ctx->udf_args_, expr_ctx))) {
LOG_WARN("failed to set udf args", K(ret));
} else if (OB_FAIL(udf_func_.process_init_func(*udf_ctx))) {
LOG_WARN("do agg init func failed", K(ret));
}
} else {
LOG_WARN("get udf ctx failed", K(ret));
}
} else if (OB_ISNULL(udf_exec_unit) || OB_ISNULL(udf_exec_unit->udf_ctx_)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("the udf ctx is null", K(ret));
}
/* process row */
if (OB_SUCC(ret)) {
udf_ctx = udf_exec_unit->udf_ctx_;
if (OB_FAIL(udf_func_.process_origin_func(result, objs_stack, param_num, expr_ctx, *udf_ctx))) {
LOG_WARN("failed to calc row", K(ret));
}
type_ctx.set_cast_mode(type_ctx.get_cast_mode() | CM_WARN_ON_FAIL);
}
return ret;
}
int ObExprDllUdf::set_udf_meta(const share::schema::ObUDFMeta& udf)
int ObExprDllUdf::deep_copy_udf_meta(share::schema::ObUDFMeta &dst,
common::ObIAllocator &alloc,
const share::schema::ObUDFMeta &src)
{
int ret = OB_SUCCESS;
udf_meta_.ret_ = udf.ret_;
udf_meta_.type_ = udf.type_;
if (OB_FAIL(ob_write_string(allocator_, udf.name_, udf_meta_.name_))) {
LOG_WARN("fail to write string", K(udf.name_), K(ret));
} else if (OB_FAIL(ob_write_string(allocator_, udf.dl_, udf_meta_.dl_))) {
LOG_WARN("fail to write string", K(udf.name_), K(ret));
} else {
}
LOG_DEBUG("set udf meta", K(udf_meta_), K(udf));
dst.ret_ = src.ret_;
dst.type_ = src.type_;
if (OB_FAIL(ob_write_string(alloc, src.name_, dst.name_))) {
LOG_WARN("fail to write string", K(src.name_), K(ret));
} else if (OB_FAIL(ob_write_string(alloc, src.dl_, dst.dl_))) {
LOG_WARN("fail to write string", K(src.name_), K(ret));
} else { }
LOG_DEBUG("set udf meta", K(src), K(dst));
return ret;
}
int ObExprDllUdf::init_udf(const common::ObIArray<ObRawExpr*>& param_exprs)
int ObExprDllUdf::set_udf_meta(const share::schema::ObUDFMeta &udf)
{
return deep_copy_udf_meta(udf_meta_, allocator_, udf);
}
int ObExprDllUdf::init_udf(const common::ObIArray<ObRawExpr*> &param_exprs)
{
int ret = OB_SUCCESS;
// this function may be invoke many times
udf_attributes_.reset();
udf_attributes_types_.reset();
calculable_results_.reset();
ARRAY_FOREACH_X(param_exprs, idx, cnt, OB_SUCC(ret))
{
ObRawExpr* expr = param_exprs.at(idx);
ARRAY_FOREACH_X(param_exprs, idx, cnt, OB_SUCC(ret)) {
ObRawExpr *expr = param_exprs.at(idx);
if (OB_ISNULL(expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("the expr is null", K(ret));
} else if (expr->is_column_ref_expr()) {
// if the input expr is a column, we should set the column name as the expr name.
ObColumnRefRawExpr* col_expr = static_cast<ObColumnRefRawExpr*>(expr);
const ObString& real_expr_name =
col_expr->get_alias_column_name().empty() ? col_expr->get_column_name() : col_expr->get_alias_column_name();
//if the input expr is a column, we should set the column name as the expr name.
ObColumnRefRawExpr *col_expr = static_cast<ObColumnRefRawExpr *>(expr);
const ObString &real_expr_name = col_expr->get_alias_column_name().empty() ? col_expr->get_column_name() : col_expr->get_alias_column_name();
expr->set_expr_name(real_expr_name);
} else if (expr->has_flag(IS_CALCULABLE_EXPR) || expr->has_flag(IS_CONST_EXPR) || expr->has_flag(IS_CONST)) {
} else if (expr->is_const_expr()) {
// TODO shengle use static engine
ret = OB_NOT_SUPPORTED;
LOG_WARN("static engine not support", K(ret));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "static engine for const udf expr");
// generate the sql expression
ObObj tmp_res;
ObNewRow empty_row;
RowDesc row_desc;
ObSqlExpression* sql_expr = NULL;
ObExprGeneratorImpl expr_generator(expr_op_factory_, 0, 0, NULL, row_desc);
if (OB_FAIL(sql_expression_factory_.alloc(sql_expr))) {
LOG_WARN("fail to alloc sql-expr", K(ret));
} else if (OB_ISNULL(sql_expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("alloc invalid expr", K(ret), K(sql_expr));
} else if (OB_FAIL(expr_generator.generate(*expr, *sql_expr))) {
LOG_WARN("generate sql expr failed", K(ret));
} else if (OB_FAIL(add_const_expression(sql_expr, idx))) {
LOG_WARN("failed to calculate", K(ret), "sql_expr", *sql_expr);
}
// ObObj tmp_res;
// ObNewRow empty_row;
// RowDesc row_desc; //空的行描述符,可计算的表达式,不需要行描述符
// ObSqlExpression *sql_expr = NULL;
// ObExprGeneratorImpl expr_generator(expr_op_factory_, 0, 0, NULL, row_desc);
// if (OB_FAIL(sql_expression_factory_.alloc(sql_expr))) {
// LOG_WARN("fail to alloc sql-expr", K(ret));
// } else if (OB_ISNULL(sql_expr)) {
// ret = OB_ERR_UNEXPECTED;
// LOG_ERROR("alloc invalid expr", K(ret), K(sql_expr));
// } else if (OB_FAIL(expr_generator.generate(*expr, *sql_expr))) {
// LOG_WARN("generate sql expr failed", K(ret));
// } else if (OB_FAIL(add_const_expression(sql_expr, idx))) {
// LOG_WARN("failed to calculate", K(ret), "sql_expr", *sql_expr);
// }
}
if (OB_SUCC(ret)) {
ObString str;
if (OB_FAIL(ob_write_string(allocator_, expr->get_expr_name(), str))) {
LOG_WARN("copy string failed", K(ret));
} else if (OB_FAIL(udf_attributes_.push_back(str))) {
if (OB_FAIL(udf_attributes_.push_back(expr->get_expr_name()))) {
LOG_WARN("failed to push back", K(ret));
} else if (OB_FAIL(udf_attributes_types_.push_back(expr->get_result_type()))) {
LOG_WARN("failed to push back", K(ret));
@ -191,7 +161,7 @@ int ObExprDllUdf::init_udf(const common::ObIArray<ObRawExpr*>& param_exprs)
return ret;
}
int ObExprDllUdf::add_const_expression(ObSqlExpression* sql_calc, int64_t idx_in_udf_arg)
int ObExprDllUdf::add_const_expression(ObSqlExpression *sql_calc, int64_t idx_in_udf_arg)
{
int ret = OB_SUCCESS;
ObUdfConstArgs const_args;
@ -211,8 +181,8 @@ OB_DEF_SERIALIZE(ObExprDllUdf)
OB_UNIS_ENCODE(udf_attributes_types_);
OB_UNIS_ENCODE(calculable_results_);
for (int64_t j = 0; j < calculable_results_.count() && OB_SUCC(ret); ++j) {
const ObUdfConstArgs& args = calculable_results_.at(j);
const ObSqlExpression* expr = args.sql_calc_;
const ObUdfConstArgs &args = calculable_results_.at(j);
const ObSqlExpression *expr = args.sql_calc_;
if (OB_ISNULL(expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("expr is null");
@ -232,7 +202,7 @@ OB_DEF_DESERIALIZE(ObExprDllUdf)
OB_UNIS_DECODE(udf_attributes_types_);
OB_UNIS_DECODE(calculable_results_);
for (int64_t j = 0; j < calculable_results_.count() && OB_SUCC(ret); ++j) {
ObSqlExpression* sql_expr = nullptr;
ObSqlExpression *sql_expr = nullptr;
if (OB_FAIL(sql_expression_factory_.alloc(sql_expr))) {
LOG_WARN("fail to alloc sql-expr", K(ret));
} else if (OB_ISNULL(sql_expr)) {
@ -255,8 +225,8 @@ OB_DEF_SERIALIZE_SIZE(ObExprDllUdf)
OB_UNIS_ADD_LEN(udf_attributes_types_);
OB_UNIS_ADD_LEN(calculable_results_);
for (int64_t j = 0; j < calculable_results_.count(); ++j) {
const ObUdfConstArgs& args = calculable_results_.at(j);
const ObSqlExpression* expr = args.sql_calc_;
const ObUdfConstArgs &args = calculable_results_.at(j);
const ObSqlExpression *expr = args.sql_calc_;
if (OB_ISNULL(expr)) {
LOG_ERROR("udf normal expr is null");
} else {
@ -267,5 +237,110 @@ OB_DEF_SERIALIZE_SIZE(ObExprDllUdf)
return len;
}
} // namespace sql
} // namespace oceanbase
int ObExprDllUdf::cg_expr(ObExprCGCtx &expr_cg_ctx,
const ObRawExpr &raw_expr,
ObExpr &rt_expr) const
{
int ret = OB_SUCCESS;
ObIAllocator &alloc = *expr_cg_ctx.allocator_;
const ObNormalDllUdfRawExpr &fun_sys = static_cast<const ObNormalDllUdfRawExpr &>(raw_expr);
ObNormalDllUdfInfo *info = OB_NEWx(ObNormalDllUdfInfo, (&alloc),
alloc, T_FUN_NORMAL_UDF);
if (NULL == info) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("allocate memory failed", K(ret));
} else {
OZ(info->from_raw_expr(fun_sys));
rt_expr.extra_info_ = info;
}
rt_expr.eval_func_ = eval_dll_udf;
return ret;
}
class ObExprDllUdfCtx : public ObExprOperatorCtx
{
public:
ObExprDllUdfCtx() : udf_func_(NULL) {}
virtual ~ObExprDllUdfCtx()
{
if (NULL != udf_func_) {
IGNORE_RETURN udf_func_->process_deinit_func(udf_ctx_);
}
}
const ObUdfFunction *udf_func_;
ObUdfFunction::ObUdfCtx udf_ctx_;
};
int ObExprDllUdf::eval_dll_udf(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res)
{
int ret = OB_SUCCESS;
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
const ObNormalDllUdfInfo *info = static_cast<ObNormalDllUdfInfo *>(expr.extra_info_);
ObExprDllUdfCtx *expr_udf_ctx = static_cast<ObExprDllUdfCtx *>(
ctx.exec_ctx_.get_expr_op_ctx(expr.expr_ctx_id_));
CK(NULL != info);
if (OB_FAIL(ret)) {
} else if (OB_FAIL(expr.eval_param_value(ctx))) {
LOG_WARN("evaluate parameters' value failed", K(ret));
} else if (OB_ISNULL(expr_udf_ctx)) {
if (OB_FAIL(ctx.exec_ctx_.create_expr_op_ctx(expr.expr_ctx_id_, expr_udf_ctx))) {
LOG_WARN("create expr op ctx failed", K(ret));
} else if (OB_ISNULL(expr_udf_ctx)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("expr udf ctx is NULL", K(ret));
} else {
ObUdfFunction::ObUdfCtx &udf_ctx = expr_udf_ctx->udf_ctx_;
OZ(ObUdfUtil::init_udf_args(ctx.exec_ctx_.get_allocator(),
info->udf_attributes_,
info->udf_attributes_types_,
udf_ctx.udf_args_));
CK(info->args_const_attr_.count() == expr.arg_cnt_);
// set const argument values
for (int64_t i = 0; OB_SUCC(ret) && i < expr.arg_cnt_; i++) {
if (info->args_const_attr_.at(i)) {
OZ(ObUdfUtil::set_udf_arg(ctx.exec_ctx_.get_allocator(),
expr.args_[i]->locate_expr_datum(ctx),
*expr.args_[i],
udf_ctx.udf_args_,
i));
}
}
if (OB_SUCC(ret)) {
expr_udf_ctx->udf_func_ = &info->udf_func_;
OZ(info->udf_func_.process_init_func(udf_ctx));
}
}
}
if (OB_SUCC(ret)) {
ObUdfFunction::ObUdfCtx &udf_ctx = expr_udf_ctx->udf_ctx_;
for (int64_t i = 0; OB_SUCC(ret) && i < expr.arg_cnt_; i++) {
OZ(ObUdfUtil::set_udf_arg(tmp_alloc_g.get_allocator(),
expr.args_[i]->locate_expr_datum(ctx),
*expr.args_[i],
udf_ctx.udf_args_,
i));
}
ObObj obj_res;
OZ(ObUdfUtil::process_udf_func(info->udf_meta_.ret_,
tmp_alloc_g.get_allocator(),
udf_ctx.udf_init_,
udf_ctx.udf_args_,
info->udf_func_.func_origin_,
obj_res));
if (OB_SUCC(ret)) {
OZ(res.from_obj(obj_res));
OZ(expr.deep_copy_datum(ctx, res));
}
}
return ret;
}
}
}