adjust allocate window function operator, enhance pq_distribute_window hint
This commit is contained in:
@ -387,24 +387,57 @@ bool ObLogWindowFunction::is_block_op() const
|
||||
int ObLogWindowFunction::print_outline_data(PlanText &plan_text)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObDMLStmt *stmt = NULL;
|
||||
const ObSelectStmt *stmt = NULL;
|
||||
ObString qb_name;
|
||||
if (OB_ISNULL(get_plan()) || OB_ISNULL(stmt = get_plan()->get_stmt())) {
|
||||
if (OB_ISNULL(get_plan()) || OB_ISNULL(stmt = dynamic_cast<const ObSelectStmt*>(get_plan()->get_stmt()))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected NULL", K(ret), K(get_plan()), K(stmt));
|
||||
} else if (get_plan()->has_added_win_dist()) {
|
||||
/* do nothing */
|
||||
} else if (OB_FAIL(stmt->get_qb_name(qb_name))) {
|
||||
LOG_WARN("get qb name failed", K(ret));
|
||||
} else {
|
||||
if (!dist_hint_.empty()) {
|
||||
ObWindowDistHint win_dist;
|
||||
if (OB_FAIL(stmt->get_qb_name(qb_name))) {
|
||||
LOG_WARN("get qb name failed", K(ret));
|
||||
} else if (OB_FAIL(win_dist.get_algos().assign(dist_hint_))) {
|
||||
LOG_WARN("array assign failed", K(ret));
|
||||
} else {
|
||||
win_dist.set_qb_name(qb_name);
|
||||
if (OB_FAIL(win_dist.print_hint(plan_text))) {
|
||||
LOG_WARN("print hint failed", K(ret));
|
||||
}
|
||||
}
|
||||
get_plan()->set_added_win_dist();
|
||||
ObWindowDistHint win_dist_hint;
|
||||
win_dist_hint.set_qb_name(qb_name);
|
||||
if (OB_FAIL(add_win_dist_options(this, stmt->get_window_func_exprs(), win_dist_hint))) {
|
||||
LOG_WARN("failed to add win dist options", K(ret));
|
||||
} else if (OB_FAIL(win_dist_hint.print_hint(plan_text))) {
|
||||
LOG_WARN("print hint failed", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLogWindowFunction::add_win_dist_options(const ObLogicalOperator *op,
|
||||
const ObIArray<ObWinFunRawExpr*> &all_win_funcs,
|
||||
ObWindowDistHint &win_dist_hint)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(op)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected NULL", K(ret), K(op));
|
||||
} else if (LOG_WINDOW_FUNCTION != op->get_type()
|
||||
&& LOG_EXCHANGE != op->get_type()
|
||||
&& LOG_SORT != op->get_type()
|
||||
&& LOG_GRANULE_ITERATOR != op->get_type()
|
||||
&& LOG_TOPK != op->get_type()
|
||||
&& LOG_MATERIAL != op->get_type()) {
|
||||
/* do nothing */
|
||||
} else if (OB_FAIL(SMART_CALL(add_win_dist_options(op->get_child(ObLogicalOperator::first_child),
|
||||
all_win_funcs,
|
||||
win_dist_hint)))) {
|
||||
LOG_WARN("failed to add win dist options", K(ret));
|
||||
} else if (LOG_WINDOW_FUNCTION == op->get_type()) {
|
||||
const ObLogWindowFunction *win_func = static_cast<const ObLogWindowFunction*>(op);
|
||||
if (win_func->is_consolidator()) {
|
||||
/* CONSOLIDATOR replaced win_expr, generate outline hint in PARTICIPATOR only */
|
||||
} else if (OB_FAIL(win_dist_hint.add_win_dist_option(all_win_funcs,
|
||||
win_func->get_window_exprs(),
|
||||
win_func->get_win_dist_algo(),
|
||||
win_func->is_push_down(),
|
||||
win_func->get_use_hash_sort()))) {
|
||||
LOG_WARN("failed to add win dist option", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -413,16 +446,35 @@ int ObLogWindowFunction::print_outline_data(PlanText &plan_text)
|
||||
int ObLogWindowFunction::print_used_hint(PlanText &plan_text)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(get_plan())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected NULL", K(ret), K(get_plan()));
|
||||
const ObWindowDistHint *win_dist_hint = NULL;
|
||||
const ObSelectStmt *stmt = NULL;
|
||||
if (OB_ISNULL(get_plan()) || OB_ISNULL(stmt = dynamic_cast<const ObSelectStmt*>(get_plan()->get_stmt()))) {
|
||||
LOG_WARN("unexpected NULL", K(ret), K(get_plan()), K(stmt));
|
||||
} else if (OB_FALSE_IT(win_dist_hint = get_plan()->get_log_plan_hint().get_window_dist())) {
|
||||
} else if (NULL == win_dist_hint || get_plan()->has_added_win_dist()) {
|
||||
/* do nothing */
|
||||
} else {
|
||||
auto win_dist = get_plan()->get_log_plan_hint().get_window_dist();
|
||||
if (NULL != win_dist && !win_dist->get_algos().empty()) {
|
||||
if (is_array_equal(dist_hint_, win_dist->get_algos())) {
|
||||
if (OB_FAIL(win_dist->print_hint(plan_text))) {
|
||||
LOG_WARN("print hint failed", K(ret));
|
||||
}
|
||||
get_plan()->set_added_win_dist();
|
||||
ObWindowDistHint outline_hint;
|
||||
if (OB_FAIL(add_win_dist_options(this, stmt->get_window_func_exprs(), outline_hint))) {
|
||||
LOG_WARN("failed to add win dist options", K(ret));
|
||||
} else if (win_dist_hint->get_win_dist_options().count() > outline_hint.get_win_dist_options().count()) {
|
||||
/* do nothing */
|
||||
} else {
|
||||
bool hint_match = true;
|
||||
const ObIArray<ObWindowDistHint::WinDistOption> &hint_opts = win_dist_hint->get_win_dist_options();
|
||||
const ObIArray<ObWindowDistHint::WinDistOption> &outline_opts = outline_hint.get_win_dist_options();
|
||||
for (int64_t i = 0; hint_match && OB_SUCC(ret) && i < hint_opts.count(); ++i) {
|
||||
const ObWindowDistHint::WinDistOption &hint_opt = hint_opts.at(i);
|
||||
const ObWindowDistHint::WinDistOption &outline_opt = outline_opts.at(i);
|
||||
hint_match = hint_opt.algo_ == outline_opt.algo_
|
||||
&& hint_opt.use_hash_sort_ == outline_opt.use_hash_sort_
|
||||
&& hint_opt.is_push_down_ == outline_opt.is_push_down_
|
||||
&& (hint_opt.win_func_idxs_.empty()
|
||||
|| is_array_equal(hint_opt.win_func_idxs_, outline_opt.win_func_idxs_));
|
||||
}
|
||||
if (OB_SUCC(ret) && hint_match && OB_FAIL(win_dist_hint->print_hint(plan_text))) {
|
||||
LOG_WARN("print hint failed", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user