bugfix: add cast when replace order expr for some special aggregation funcs

This commit is contained in:
JinmaoLi
2024-05-11 10:07:05 +00:00
committed by ob-robot
parent 2b8def2dce
commit 693d2a2824
4 changed files with 25 additions and 8 deletions

View File

@ -3847,6 +3847,18 @@ ObRawExpr *&ObAggFunRawExpr::get_param_expr(int64_t index)
}
}
int ObAggFunRawExpr::get_param_exprs(common::ObIArray<ObRawExpr*> &param_exprs)
{
int ret = OB_SUCCESS;
int64_t param_count = get_param_count();
for (int64_t i = 0; OB_SUCC(ret) && i < param_count; ++i) {
if (OB_FAIL(param_exprs.push_back(get_param_expr(i)))) {
LOG_WARN("fail to push back param expr", K(ret));
}
}
return ret;
}
int ObAggFunRawExpr::do_visit(ObRawExprVisitor &visitor)
{

View File

@ -3432,6 +3432,7 @@ public:
virtual ObRawExpr *&get_param_expr(int64_t index);
inline int64_t get_real_param_count() const { return real_param_exprs_.count(); }
inline const common::ObIArray<ObRawExpr*> &get_real_param_exprs() const { return real_param_exprs_; }
int get_param_exprs(common::ObIArray<ObRawExpr*> &param_exprs);
inline common::ObIArray<ObRawExpr*> &get_real_param_exprs_for_update() { return real_param_exprs_; }
virtual int do_visit(ObRawExprVisitor &visitor) override;
inline ObRawExpr *get_separator_param_expr() const { return separator_param_expr_; }

View File

@ -1375,8 +1375,12 @@ int ObTransformConstPropagate::check_need_cast_when_replace(ObRawExpr *expr,
need_cast = true;
} else if (parent_expr->is_win_func_expr()) {
ObWinFunRawExpr *win_expr = static_cast<ObWinFunRawExpr*>(parent_expr);
if (OB_NOT_NULL(win_expr->get_agg_expr()) &&
ObOptimizerUtil::find_item(win_expr->get_agg_expr()->get_real_param_exprs(), expr)) {
ObAggFunRawExpr *agg_expr = win_expr->get_agg_expr();
ObSEArray<ObRawExpr*,4> agg_params;
if (OB_NOT_NULL(agg_expr) && OB_FAIL(agg_expr->get_param_exprs(agg_params))) {
// Type deduction of some aggr funcs relies on not only real params, e.g. MEDIAN, GROUP_PERCENTILE_CONT
LOG_WARN("failed to get agg params", K(ret));
} else if (OB_NOT_NULL(agg_expr) && ObOptimizerUtil::find_item(agg_params, expr)) {
need_cast = true;
} else if (ObOptimizerUtil::find_item(win_expr->get_func_params(), expr)) {
need_cast = true;