Implement user-defined aggregate function overloading
This commit is contained in:
@ -15,6 +15,8 @@
|
|||||||
#include "sql/ob_spi.h"
|
#include "sql/ob_spi.h"
|
||||||
#include "pl/ob_pl.h"
|
#include "pl/ob_pl.h"
|
||||||
#include "pl/ob_pl_stmt.h"
|
#include "pl/ob_pl_stmt.h"
|
||||||
|
#include "pl/ob_pl_resolver.h"
|
||||||
|
#include "sql/resolver/ob_resolver_utils.h"
|
||||||
|
|
||||||
namespace oceanbase
|
namespace oceanbase
|
||||||
{
|
{
|
||||||
@ -23,8 +25,46 @@ using namespace share::schema;
|
|||||||
namespace sql
|
namespace sql
|
||||||
{
|
{
|
||||||
|
|
||||||
|
int ObPlAggUdfFunction::pick_routine(ObSEArray<const ObIRoutineInfo *, 4> &routine_infos,
|
||||||
|
const ObIRoutineInfo *&routine_info,
|
||||||
|
ObIArray<ObExprResType> ¶m_type)
|
||||||
|
{
|
||||||
|
int ret = OB_SUCCESS;
|
||||||
|
routine_info = NULL;
|
||||||
|
if (routine_infos.count() == 1) {
|
||||||
|
routine_info = routine_infos.at(0);
|
||||||
|
} else {
|
||||||
|
ObSEArray<ObRawExpr *, 4> mock_exec_expr;
|
||||||
|
ObRawExprFactory *expr_factory = exec_ctx_->get_expr_factory();
|
||||||
|
CK (OB_NOT_NULL(expr_factory));
|
||||||
|
CK (OB_NOT_NULL(allocator_));
|
||||||
|
CK (OB_NOT_NULL(session_info_));
|
||||||
|
CK (OB_NOT_NULL(exec_ctx_->get_sql_ctx()));
|
||||||
|
CK (OB_NOT_NULL(exec_ctx_->get_sql_ctx()->schema_guard_));
|
||||||
|
CK (OB_NOT_NULL(exec_ctx_->get_sql_proxy()));
|
||||||
|
for (int64_t i = 0; OB_SUCC(ret) && i < param_type.count(); ++i) {
|
||||||
|
ObConstRawExpr *c_expr = NULL;
|
||||||
|
OZ (expr_factory->create_raw_expr(T_QUESTIONMARK, c_expr));
|
||||||
|
OX (c_expr->set_result_type(param_type.at(i)));
|
||||||
|
OZ (mock_exec_expr.push_back(c_expr));
|
||||||
|
}
|
||||||
|
if (OB_SUCC(ret)) {
|
||||||
|
pl::ObPLPackageGuard package_guard(session_info_->get_effective_tenant_id());
|
||||||
|
pl::ObPLResolveCtx resolve_ctx(*allocator_,
|
||||||
|
*session_info_,
|
||||||
|
*exec_ctx_->get_sql_ctx()->schema_guard_,
|
||||||
|
package_guard,
|
||||||
|
*exec_ctx_->get_sql_proxy(),
|
||||||
|
false /*is_ps*/);
|
||||||
|
OZ (ObResolverUtils::pick_routine(resolve_ctx, mock_exec_expr, routine_infos, routine_info));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int ObPlAggUdfFunction::get_package_routine_info(const ObString &routine_name,
|
int ObPlAggUdfFunction::get_package_routine_info(const ObString &routine_name,
|
||||||
const ObRoutineInfo *&routine_info)
|
const ObRoutineInfo *&routine_info,
|
||||||
|
ObIArray<ObExprResType> ¶m_type)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
ObSqlCtx *sql_ctx = NULL;
|
ObSqlCtx *sql_ctx = NULL;
|
||||||
@ -32,6 +72,7 @@ int ObPlAggUdfFunction::get_package_routine_info(const ObString &routine_name,
|
|||||||
ObSEArray<const ObIRoutineInfo *, 4> routine_infos;
|
ObSEArray<const ObIRoutineInfo *, 4> routine_infos;
|
||||||
ObRoutineType routine_type = share::schema::ObRoutineType::ROUTINE_FUNCTION_TYPE;
|
ObRoutineType routine_type = share::schema::ObRoutineType::ROUTINE_FUNCTION_TYPE;
|
||||||
routine_info = NULL;
|
routine_info = NULL;
|
||||||
|
const ObIRoutineInfo *base_routine_info = NULL;
|
||||||
const ObUDTTypeInfo *udt_info = NULL;
|
const ObUDTTypeInfo *udt_info = NULL;
|
||||||
if (OB_ISNULL(session_info_) || OB_ISNULL(exec_ctx_) ||
|
if (OB_ISNULL(session_info_) || OB_ISNULL(exec_ctx_) ||
|
||||||
OB_ISNULL(sql_ctx = exec_ctx_->get_sql_ctx()) ||
|
OB_ISNULL(sql_ctx = exec_ctx_->get_sql_ctx()) ||
|
||||||
@ -51,8 +92,10 @@ int ObPlAggUdfFunction::get_package_routine_info(const ObString &routine_name,
|
|||||||
routine_type,
|
routine_type,
|
||||||
routine_infos))) {
|
routine_infos))) {
|
||||||
LOG_WARN("failed to get package routine infos", K(ret));
|
LOG_WARN("failed to get package routine infos", K(ret));
|
||||||
} else if (OB_UNLIKELY(routine_infos.count() != 1) ||
|
} else if (OB_FAIL(pick_routine(routine_infos, base_routine_info, param_type))) {
|
||||||
OB_ISNULL(routine_info = static_cast<const ObRoutineInfo *>(routine_infos.at(0)))) {
|
LOG_WARN("get unexpected error", K(routine_infos), K(base_routine_info), K(ret));
|
||||||
|
} else if (OB_ISNULL(base_routine_info) ||
|
||||||
|
OB_ISNULL(routine_info = static_cast<const ObRoutineInfo *>(base_routine_info))) {
|
||||||
ret = OB_ERR_UNEXPECTED;
|
ret = OB_ERR_UNEXPECTED;
|
||||||
LOG_WARN("get unexpected error", K(routine_infos), K(routine_info), K(ret));
|
LOG_WARN("get unexpected error", K(routine_infos), K(routine_info), K(ret));
|
||||||
} else {
|
} else {
|
||||||
@ -208,11 +251,9 @@ int ObPlAggUdfFunction::process_init_pl_agg_udf(ObObjParam &pl_obj)
|
|||||||
OB_ISNULL(exec_ctx_->get_sql_ctx()->schema_guard_) || OB_ISNULL(allocator_)) {
|
OB_ISNULL(exec_ctx_->get_sql_ctx()->schema_guard_) || OB_ISNULL(allocator_)) {
|
||||||
ret = OB_ERR_UNEXPECTED;
|
ret = OB_ERR_UNEXPECTED;
|
||||||
LOG_WARN("get unexpected null", K(ret), K(exec_ctx_), K(allocator_));
|
LOG_WARN("get unexpected null", K(ret), K(exec_ctx_), K(allocator_));
|
||||||
} else if (OB_FAIL(get_package_routine_info(routine_name, routine_info))) {
|
|
||||||
LOG_WARN("failed to get package routine info", K(ret));
|
|
||||||
} else {
|
} else {
|
||||||
ObSEArray<ObUDFParamDesc, 4> params_desc;
|
ObSEArray<ObUDFParamDesc, 5> params_desc;
|
||||||
ObSEArray<ObExprResType, 4> params_type;
|
ObSEArray<ObExprResType, 5> params_type;
|
||||||
pl::ObPLUDTNS ns(*exec_ctx_->get_sql_ctx()->schema_guard_);
|
pl::ObPLUDTNS ns(*exec_ctx_->get_sql_ctx()->schema_guard_);
|
||||||
pl::ObPLDataType pl_type;
|
pl::ObPLDataType pl_type;
|
||||||
pl_type.set_user_type_id(pl::PL_RECORD_TYPE, type_id_);
|
pl_type.set_user_type_id(pl::PL_RECORD_TYPE, type_id_);
|
||||||
@ -232,11 +273,14 @@ int ObPlAggUdfFunction::process_init_pl_agg_udf(ObObjParam &pl_obj)
|
|||||||
common::ObArenaAllocator alloc;
|
common::ObArenaAllocator alloc;
|
||||||
ObExprResType param_type(alloc);
|
ObExprResType param_type(alloc);
|
||||||
param_type.set_ext();
|
param_type.set_ext();
|
||||||
|
param_type.set_udt_id(type_id_);
|
||||||
if (OB_FAIL(params_type.push_back(param_type))) {
|
if (OB_FAIL(params_type.push_back(param_type))) {
|
||||||
LOG_WARN("failed to push back type", K(ret));
|
LOG_WARN("failed to push back type", K(ret));
|
||||||
} else if (OB_FAIL(params_desc.push_back(
|
} else if (OB_FAIL(params_desc.push_back(
|
||||||
ObUDFParamDesc(ObUDFParamDesc::OutType::LOCAL_OUT, 0)))) {
|
ObUDFParamDesc(ObUDFParamDesc::OutType::LOCAL_OUT, 0)))) {
|
||||||
LOG_WARN("failed to push back param desc", K(ret));
|
LOG_WARN("failed to push back param desc", K(ret));
|
||||||
|
} else if (OB_FAIL(get_package_routine_info(routine_name, routine_info, params_type))) {
|
||||||
|
LOG_WARN("failed to get package routine info", K(ret));
|
||||||
} else if (OB_FAIL(call_pl_engine_exectue_udf(*udf_params, routine_info, tmp_result))) {
|
} else if (OB_FAIL(call_pl_engine_exectue_udf(*udf_params, routine_info, tmp_result))) {
|
||||||
LOG_WARN("failed to call pl engine exectue udf", K(ret));
|
LOG_WARN("failed to call pl engine exectue udf", K(ret));
|
||||||
} else if (OB_UNLIKELY(udf_params->count() < 1)) {
|
} else if (OB_UNLIKELY(udf_params->count() < 1)) {
|
||||||
@ -269,8 +313,6 @@ int ObPlAggUdfFunction::process_calc_pl_agg_udf(ObObjParam &pl_obj,
|
|||||||
LOG_WARN("failed to check params validty", K(ret));
|
LOG_WARN("failed to check params validty", K(ret));
|
||||||
} else if (is_null_params) {
|
} else if (is_null_params) {
|
||||||
/*no nothing*/
|
/*no nothing*/
|
||||||
} else if (OB_FAIL(get_package_routine_info(routine_name, routine_info))) {
|
|
||||||
LOG_WARN("failed to get package routine info", K(ret));
|
|
||||||
} else if (OB_FAIL(process_obj_params(const_cast<ObObj*>(obj_params), param_num))) {
|
} else if (OB_FAIL(process_obj_params(const_cast<ObObj*>(obj_params), param_num))) {
|
||||||
LOG_WARN("failed to process obj params", K(ret));
|
LOG_WARN("failed to process obj params", K(ret));
|
||||||
} else {
|
} else {
|
||||||
@ -284,6 +326,7 @@ int ObPlAggUdfFunction::process_calc_pl_agg_udf(ObObjParam &pl_obj,
|
|||||||
common::ObArenaAllocator alloc;
|
common::ObArenaAllocator alloc;
|
||||||
ObExprResType param_type(alloc);
|
ObExprResType param_type(alloc);
|
||||||
param_type.set_ext();
|
param_type.set_ext();
|
||||||
|
param_type.set_udt_id(type_id_);
|
||||||
if (OB_FAIL(all_params_type.push_back(param_type))) {
|
if (OB_FAIL(all_params_type.push_back(param_type))) {
|
||||||
LOG_WARN("failed to push back type", K(ret));
|
LOG_WARN("failed to push back type", K(ret));
|
||||||
} else if (OB_FAIL(all_params_desc.push_back(
|
} else if (OB_FAIL(all_params_desc.push_back(
|
||||||
@ -308,6 +351,8 @@ int ObPlAggUdfFunction::process_calc_pl_agg_udf(ObObjParam &pl_obj,
|
|||||||
} else if (OB_ISNULL(udf_params)) {
|
} else if (OB_ISNULL(udf_params)) {
|
||||||
ret = OB_ERR_UNEXPECTED;
|
ret = OB_ERR_UNEXPECTED;
|
||||||
LOG_WARN("get unexpected null", K(ret));
|
LOG_WARN("get unexpected null", K(ret));
|
||||||
|
} else if (OB_FAIL(get_package_routine_info(routine_name, routine_info, all_params_type))) {
|
||||||
|
LOG_WARN("failed to get package routine info", K(ret));
|
||||||
} else if (OB_FAIL(call_pl_engine_exectue_udf(*udf_params, routine_info, tmp_result))) {
|
} else if (OB_FAIL(call_pl_engine_exectue_udf(*udf_params, routine_info, tmp_result))) {
|
||||||
LOG_WARN("failed to call pl engine exectue udf", K(ret));
|
LOG_WARN("failed to call pl engine exectue udf", K(ret));
|
||||||
} else if (OB_UNLIKELY(udf_params->count() < 1)) {
|
} else if (OB_UNLIKELY(udf_params->count() < 1)) {
|
||||||
@ -354,48 +399,49 @@ int ObPlAggUdfFunction::process_merge_pl_agg_udf(ObObjParam &pl_obj,
|
|||||||
ObString routine_name(strlen(str), str);
|
ObString routine_name(strlen(str), str);
|
||||||
ParamStore *udf_params = NULL;
|
ParamStore *udf_params = NULL;
|
||||||
ObObj tmp_result;
|
ObObj tmp_result;
|
||||||
if (OB_FAIL(get_package_routine_info(routine_name, routine_info))) {
|
|
||||||
|
//for pl agg udf, type member ODCIAggregateMerge() the first param must be self and is IN OUT,
|
||||||
|
//the second param is IN. so we need rebuild relation infos.
|
||||||
|
//see oracle url:https://docs.oracle.com/cd/B28359_01/appdev.111/b28425/ext_agg_ref.htm#CACBJHHI
|
||||||
|
ObSEArray<ObExprResType, 4> params_type;
|
||||||
|
ObSEArray<ObUDFParamDesc, 4> params_desc;
|
||||||
|
ObSEArray<ObUDFParamDesc, 4> all_params_desc;
|
||||||
|
ObSEArray<ObExprResType, 4> all_params_type;
|
||||||
|
common::ObArenaAllocator alloc;
|
||||||
|
ObExprResType param_type(alloc);
|
||||||
|
param_type.set_ext();
|
||||||
|
param_type.set_udt_id(type_id_);
|
||||||
|
if (OB_FAIL(params_type.push_back(param_type))) {
|
||||||
|
LOG_WARN("failed to push back type", K(ret));
|
||||||
|
} else if (OB_FAIL(params_desc.push_back(ObUDFParamDesc()))) {
|
||||||
|
LOG_WARN("failed to push back param desc", K(ret));
|
||||||
|
} else if (OB_FAIL(build_in_params_store(pl_obj, true, &pl_obj2, 1, params_desc,
|
||||||
|
params_type, udf_params))) {
|
||||||
|
LOG_WARN("failed to build in params store", K(ret));
|
||||||
|
} else if (OB_ISNULL(udf_params)) {
|
||||||
|
ret = OB_ERR_UNEXPECTED;
|
||||||
|
LOG_WARN("get unexpected null", K(ret));
|
||||||
|
} else if (OB_FAIL(all_params_type.push_back(param_type))) {
|
||||||
|
LOG_WARN("failed to push back type", K(ret));
|
||||||
|
} else if (OB_FAIL(all_params_desc.push_back(
|
||||||
|
ObUDFParamDesc(ObUDFParamDesc::LOCAL_OUT, 0)))) {
|
||||||
|
LOG_WARN("failed to push back param desc", K(ret));
|
||||||
|
} else if (OB_FAIL(all_params_type.push_back(param_type))) {
|
||||||
|
LOG_WARN("failed to push back type", K(ret));
|
||||||
|
} else if (OB_FAIL(all_params_desc.push_back(ObUDFParamDesc()))) {
|
||||||
|
LOG_WARN("failed to push back param desc", K(ret));
|
||||||
|
} else if (OB_FAIL(get_package_routine_info(routine_name, routine_info, all_params_type))) {
|
||||||
LOG_WARN("failed to get package routine info", K(ret));
|
LOG_WARN("failed to get package routine info", K(ret));
|
||||||
|
} else if (OB_FAIL(call_pl_engine_exectue_udf(*udf_params, routine_info, tmp_result))) {
|
||||||
|
LOG_WARN("failed to call pl engine exectue udf", K(ret));
|
||||||
|
} else if (OB_UNLIKELY(udf_params->count() < 1)) {
|
||||||
|
ret = OB_ERR_UNEXPECTED;
|
||||||
|
LOG_WARN("get unexpected error", K(ret), K(udf_params->count()));
|
||||||
} else {
|
} else {
|
||||||
//for pl agg udf, type member ODCIAggregateMerge() the first param must be self and is IN OUT,
|
udf_params->at(0).copy_value_or_obj(pl_obj, true);
|
||||||
//the second param is IN. so we need rebuild relation infos.
|
LOG_TRACE("Succeed to process merge pl agg udf", K(pl_obj), K(tmp_result));
|
||||||
//see oracle url:https://docs.oracle.com/cd/B28359_01/appdev.111/b28425/ext_agg_ref.htm#CACBJHHI
|
|
||||||
ObSEArray<ObUDFParamDesc, 4> params_desc;
|
|
||||||
ObSEArray<ObUDFParamDesc, 4> all_params_desc;
|
|
||||||
ObSEArray<ObExprResType, 4> params_type;
|
|
||||||
ObSEArray<ObExprResType, 4> all_params_type;
|
|
||||||
common::ObArenaAllocator alloc;
|
|
||||||
ObExprResType param_type(alloc);
|
|
||||||
param_type.set_ext();
|
|
||||||
if (OB_FAIL(params_type.push_back(param_type))) {
|
|
||||||
LOG_WARN("failed to push back type", K(ret));
|
|
||||||
} else if (OB_FAIL(params_desc.push_back(ObUDFParamDesc()))) {
|
|
||||||
LOG_WARN("failed to push back param desc", K(ret));
|
|
||||||
} else if (OB_FAIL(build_in_params_store(pl_obj, true, &pl_obj2, 1, params_desc,
|
|
||||||
params_type, udf_params))) {
|
|
||||||
LOG_WARN("failed to build in params store", K(ret));
|
|
||||||
} else if (OB_ISNULL(udf_params)) {
|
|
||||||
ret = OB_ERR_UNEXPECTED;
|
|
||||||
LOG_WARN("get unexpected null", K(ret));
|
|
||||||
} else if (OB_FAIL(all_params_type.push_back(param_type))) {
|
|
||||||
LOG_WARN("failed to push back type", K(ret));
|
|
||||||
} else if (OB_FAIL(all_params_desc.push_back(
|
|
||||||
ObUDFParamDesc(ObUDFParamDesc::LOCAL_OUT, 0)))) {
|
|
||||||
LOG_WARN("failed to push back param desc", K(ret));
|
|
||||||
} else if (OB_FAIL(all_params_type.push_back(param_type))) {
|
|
||||||
LOG_WARN("failed to push back type", K(ret));
|
|
||||||
} else if (OB_FAIL(all_params_desc.push_back(ObUDFParamDesc()))) {
|
|
||||||
LOG_WARN("failed to push back param desc", K(ret));
|
|
||||||
} else if (OB_FAIL(call_pl_engine_exectue_udf(*udf_params, routine_info, tmp_result))) {
|
|
||||||
LOG_WARN("failed to call pl engine exectue udf", K(ret));
|
|
||||||
} else if (OB_UNLIKELY(udf_params->count() < 1)) {
|
|
||||||
ret = OB_ERR_UNEXPECTED;
|
|
||||||
LOG_WARN("get unexpected error", K(ret), K(udf_params->count()));
|
|
||||||
} else {
|
|
||||||
udf_params->at(0).copy_value_or_obj(pl_obj, true);
|
|
||||||
LOG_TRACE("Succeed to process merge pl agg udf", K(pl_obj), K(tmp_result));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,80 +454,81 @@ int ObPlAggUdfFunction::process_get_pl_agg_udf_result(ObObjParam &pl_obj,
|
|||||||
ObString routine_name(strlen(str), str);
|
ObString routine_name(strlen(str), str);
|
||||||
ParamStore *udf_params = NULL;
|
ParamStore *udf_params = NULL;
|
||||||
ObObj tmp_result;
|
ObObj tmp_result;
|
||||||
if (OB_FAIL(get_package_routine_info(routine_name, routine_info))) {
|
|
||||||
LOG_WARN("failed to get package routine info", K(ret));
|
//for pl agg udf, type member ODCIAggregateTerminate() the first param must be self and is IN,
|
||||||
|
//the second param is OUT, the third param is number. so we need rebuild relation infos.
|
||||||
|
//see oracle url:https://docs.oracle.com/cd/B28359_01/appdev.111/b28425/ext_agg_ref.htm#CACBJHHI
|
||||||
|
ObSEArray<ObUDFParamDesc, 4> params_desc;
|
||||||
|
ObSEArray<ObUDFParamDesc, 4> all_params_desc;
|
||||||
|
ObSEArray<ObExprResType, 4> params_type;
|
||||||
|
ObSEArray<ObExprResType, 4> all_params_type;
|
||||||
|
result.set_meta_type(result_type_);
|
||||||
|
if (OB_FAIL(params_type.push_back(result_type_))) {
|
||||||
|
LOG_WARN("failed to push back type", K(ret));
|
||||||
|
} else if (OB_FAIL(params_desc.push_back(
|
||||||
|
ObUDFParamDesc(ObUDFParamDesc::LOCAL_OUT, 0)))) {
|
||||||
|
LOG_WARN("failed to push back param desc", K(ret));
|
||||||
|
} else if (OB_FAIL(build_in_params_store(pl_obj, false, &result, 1, params_desc,
|
||||||
|
params_type, udf_params))) {
|
||||||
|
LOG_WARN("failed to build in params store", K(ret));
|
||||||
|
} else if (OB_ISNULL(udf_params)) {
|
||||||
|
ret = OB_ERR_UNEXPECTED;
|
||||||
|
LOG_WARN("get unexpected null", K(ret));
|
||||||
} else {
|
} else {
|
||||||
//for pl agg udf, type member ODCIAggregateTerminate() the first param must be self and is IN,
|
common::ObArenaAllocator alloc;
|
||||||
//the second param is OUT, the third param is number. so we need rebuild relation infos.
|
ObExprResType param_type(alloc);
|
||||||
//see oracle url:https://docs.oracle.com/cd/B28359_01/appdev.111/b28425/ext_agg_ref.htm#CACBJHHI
|
ObExprResType flags_type(alloc);
|
||||||
ObSEArray<ObUDFParamDesc, 4> params_desc;
|
param_type.set_ext();
|
||||||
ObSEArray<ObUDFParamDesc, 4> all_params_desc;
|
param_type.set_udt_id(type_id_);
|
||||||
ObSEArray<ObExprResType, 4> params_type;
|
flags_type.set_number();
|
||||||
ObSEArray<ObExprResType, 4> all_params_type;
|
number::ObNumber num;
|
||||||
result.set_meta_type(result_type_);
|
ObObj number;
|
||||||
if (OB_FAIL(params_type.push_back(result_type_))) {
|
number.set_number(ObNumberType, num);
|
||||||
|
ObObjParam param;
|
||||||
|
param.reset();
|
||||||
|
number.copy_value_or_obj(param, true);
|
||||||
|
if (OB_FAIL(udf_params->push_back(param))) {
|
||||||
|
LOG_WARN("failed to push back obj param");
|
||||||
|
} else if (OB_FAIL(all_params_type.push_back(param_type))) {
|
||||||
LOG_WARN("failed to push back type", K(ret));
|
LOG_WARN("failed to push back type", K(ret));
|
||||||
} else if (OB_FAIL(params_desc.push_back(
|
} else if (OB_FAIL(all_params_desc.push_back(ObUDFParamDesc()))) {
|
||||||
ObUDFParamDesc(ObUDFParamDesc::LOCAL_OUT, 0)))) {
|
|
||||||
LOG_WARN("failed to push back param desc", K(ret));
|
LOG_WARN("failed to push back param desc", K(ret));
|
||||||
} else if (OB_FAIL(build_in_params_store(pl_obj, false, &result, 1, params_desc,
|
} else if (OB_FAIL(all_params_type.push_back(result_type_))) {
|
||||||
params_type, udf_params))) {
|
LOG_WARN("failed to push back type", K(ret));
|
||||||
LOG_WARN("failed to build in params store", K(ret));
|
} else if (OB_FAIL(all_params_desc.push_back(
|
||||||
} else if (OB_ISNULL(udf_params)) {
|
ObUDFParamDesc(ObUDFParamDesc::LOCAL_OUT, 1)))) {
|
||||||
|
LOG_WARN("failed to push back param desc", K(ret));
|
||||||
|
} else if (OB_FAIL(all_params_type.push_back(flags_type))) {
|
||||||
|
LOG_WARN("failed to push back type", K(ret));
|
||||||
|
} else if (OB_FAIL(all_params_desc.push_back(ObUDFParamDesc()))) {
|
||||||
|
LOG_WARN("failed to push back param desc", K(ret));
|
||||||
|
} else if (OB_FAIL(get_package_routine_info(routine_name, routine_info, all_params_type))) {
|
||||||
|
LOG_WARN("failed to get package routine info", K(ret));
|
||||||
|
} else if (OB_FAIL(call_pl_engine_exectue_udf(*udf_params, routine_info, tmp_result))) {
|
||||||
|
LOG_WARN("failed to call pl engine exectue udf", K(ret));
|
||||||
|
} else if (OB_UNLIKELY(udf_params->count() < 2)) {
|
||||||
ret = OB_ERR_UNEXPECTED;
|
ret = OB_ERR_UNEXPECTED;
|
||||||
LOG_WARN("get unexpected null", K(ret));
|
LOG_WARN("get unexpected error", K(ret), K(udf_params->count()));
|
||||||
} else {
|
} else if (!ob_is_lob_tc(result_type_.get_type())) {
|
||||||
common::ObArenaAllocator alloc;
|
ObObj src_obj;
|
||||||
ObExprResType param_type(alloc);
|
udf_params->at(1).copy_value_or_obj(src_obj, true);
|
||||||
ObExprResType flags_type(alloc);
|
ObCastMode cast_mode = CM_NONE;
|
||||||
param_type.set_ext();
|
if (OB_FAIL(ObSQLUtils::get_default_cast_mode(session_info_, cast_mode))) {
|
||||||
flags_type.set_number();
|
LOG_WARN("failed to get default cast mode", K(ret));
|
||||||
number::ObNumber num;
|
|
||||||
ObObj number;
|
|
||||||
number.set_number(ObNumberType, num);
|
|
||||||
ObObjParam param;
|
|
||||||
param.reset();
|
|
||||||
number.copy_value_or_obj(param, true);
|
|
||||||
if (OB_FAIL(udf_params->push_back(param))) {
|
|
||||||
LOG_WARN("failed to push back obj param");
|
|
||||||
} else if (OB_FAIL(all_params_type.push_back(param_type))) {
|
|
||||||
LOG_WARN("failed to push back type", K(ret));
|
|
||||||
} else if (OB_FAIL(all_params_desc.push_back(ObUDFParamDesc()))) {
|
|
||||||
LOG_WARN("failed to push back param desc", K(ret));
|
|
||||||
} else if (OB_FAIL(all_params_type.push_back(result_type_))) {
|
|
||||||
LOG_WARN("failed to push back type", K(ret));
|
|
||||||
} else if (OB_FAIL(all_params_desc.push_back(
|
|
||||||
ObUDFParamDesc(ObUDFParamDesc::LOCAL_OUT, 1)))) {
|
|
||||||
LOG_WARN("failed to push back param desc", K(ret));
|
|
||||||
} else if (OB_FAIL(all_params_type.push_back(flags_type))) {
|
|
||||||
LOG_WARN("failed to push back type", K(ret));
|
|
||||||
} else if (OB_FAIL(all_params_desc.push_back(ObUDFParamDesc()))) {
|
|
||||||
LOG_WARN("failed to push back param desc", K(ret));
|
|
||||||
} else if (OB_FAIL(call_pl_engine_exectue_udf(*udf_params, routine_info, tmp_result))) {
|
|
||||||
LOG_WARN("failed to call pl engine exectue udf", K(ret));
|
|
||||||
} else if (OB_UNLIKELY(udf_params->count() < 2)) {
|
|
||||||
ret = OB_ERR_UNEXPECTED;
|
|
||||||
LOG_WARN("get unexpected error", K(ret), K(udf_params->count()));
|
|
||||||
} else if (!ob_is_lob_tc(result_type_.get_type())) {
|
|
||||||
ObObj src_obj;
|
|
||||||
udf_params->at(1).copy_value_or_obj(src_obj, true);
|
|
||||||
ObCastMode cast_mode = CM_NONE;
|
|
||||||
if (OB_FAIL(ObSQLUtils::get_default_cast_mode(session_info_, cast_mode))) {
|
|
||||||
LOG_WARN("failed to get default cast mode", K(ret));
|
|
||||||
} else {
|
|
||||||
ObCastCtx cast_ctx(allocator_, NULL, cast_mode, ObCharset::get_system_collation(), NULL);
|
|
||||||
if (OB_FAIL(ObObjCaster::to_type(result_type_.get_type(), cast_ctx, src_obj, result))) {
|
|
||||||
LOG_WARN("failed to cast type", K(ret));
|
|
||||||
} else {
|
|
||||||
LOG_TRACE("succeed to process get pl agg udf result", K(src_obj), K(result));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
udf_params->at(1).copy_value_or_obj(result, true);
|
ObCastCtx cast_ctx(allocator_, NULL, cast_mode, ObCharset::get_system_collation(), NULL);
|
||||||
LOG_TRACE("succeed to process get pl agg udf result", K(result));
|
if (OB_FAIL(ObObjCaster::to_type(result_type_.get_type(), cast_ctx, src_obj, result))) {
|
||||||
|
LOG_WARN("failed to cast type", K(ret));
|
||||||
|
} else {
|
||||||
|
LOG_TRACE("succeed to process get pl agg udf result", K(src_obj), K(result));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
udf_params->at(1).copy_value_or_obj(result, true);
|
||||||
|
LOG_TRACE("succeed to process get pl agg udf result", K(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -72,8 +72,13 @@ class ObPlAggUdfFunction
|
|||||||
int get_package_udf_id(const ObString &routine_name,
|
int get_package_udf_id(const ObString &routine_name,
|
||||||
const share::schema::ObRoutineInfo *&routine_info);
|
const share::schema::ObRoutineInfo *&routine_info);
|
||||||
|
|
||||||
|
int pick_routine(ObSEArray<const ObIRoutineInfo *, 4> &routine_infos,
|
||||||
|
const ObIRoutineInfo *&routine_info,
|
||||||
|
ObIArray<ObExprResType> ¶m_type);
|
||||||
|
|
||||||
int get_package_routine_info(const ObString &routine_name,
|
int get_package_routine_info(const ObString &routine_name,
|
||||||
const share::schema::ObRoutineInfo *&routine_info);
|
const share::schema::ObRoutineInfo *&routine_info,
|
||||||
|
ObIArray<ObExprResType> ¶m_type);
|
||||||
|
|
||||||
int check_types(const ObObj *obj_params,
|
int check_types(const ObObj *obj_params,
|
||||||
int64_t param_num,
|
int64_t param_num,
|
||||||
|
|||||||
Reference in New Issue
Block a user