adjust allocate window function operator, enhance pq_distribute_window hint
This commit is contained in:
@ -952,7 +952,7 @@ const char* ObHint::get_hint_name(ObItemType type, bool is_enable_hint /* defaul
|
||||
case T_USE_HASH_AGGREGATE: return is_enable_hint ? "USE_HASH_AGGREGATION"
|
||||
: "NO_USE_HASH_AGGREGATION";
|
||||
case T_TABLE_PARALLEL: return "PARALLEL";
|
||||
case T_PQ_DISTRIBUTE_WINDOW: return "PQ_DISIRIBUTE_WINDOW";
|
||||
case T_PQ_DISTRIBUTE_WINDOW: return "PQ_DISTRIBUTE_WINDOW";
|
||||
case T_GBY_PUSHDOWN: return is_enable_hint ? "GBY_PUSHDOWN" : "NO_GBY_PUSHDOWN";
|
||||
case T_USE_HASH_DISTINCT: return is_enable_hint ? "USE_HASH_DISTINCT" : "NO_USE_HASH_DISTINCT";
|
||||
case T_DISTINCT_PUSHDOWN: return is_enable_hint ? "DISTINCT_PUSHDOWN" : "NO_DISTINCT_PUSHDOWN";
|
||||
@ -2561,10 +2561,10 @@ void ObTableInHint::set_table(const TableItem& table)
|
||||
const char *ObWindowDistHint::get_dist_algo_str(WinDistAlgo dist_algo)
|
||||
{
|
||||
switch (dist_algo) {
|
||||
case WinDistAlgo::NONE: return "NONE";
|
||||
case WinDistAlgo::HASH: return "HASH";
|
||||
case WinDistAlgo::RANGE: return "RANGE";
|
||||
case WinDistAlgo::LIST: return "LIST";
|
||||
case WinDistAlgo::WIN_DIST_NONE: return "NONE";
|
||||
case WinDistAlgo::WIN_DIST_HASH: return "HASH";
|
||||
case WinDistAlgo::WIN_DIST_RANGE: return "RANGE";
|
||||
case WinDistAlgo::WIN_DIST_LIST: return "LIST";
|
||||
default: return NULL;
|
||||
}
|
||||
return NULL;
|
||||
@ -2573,17 +2573,130 @@ const char *ObWindowDistHint::get_dist_algo_str(WinDistAlgo dist_algo)
|
||||
int ObWindowDistHint::print_hint_desc(PlanText &plan_text) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
char *buf = plan_text.buf_;
|
||||
int64_t &buf_len = plan_text.buf_len_;
|
||||
int64_t &pos = plan_text.pos_;
|
||||
FOREACH_CNT_X(v, algos_, OB_SUCC(ret)) {
|
||||
if (OB_FAIL(BUF_PRINTF(" %s", get_dist_algo_str(*v)))) {
|
||||
LOG_WARN("print failed", K(ret));
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < win_dist_options_.count(); ++i) {
|
||||
if (OB_FAIL(win_dist_options_.at(i).print_win_dist_option(plan_text))) {
|
||||
LOG_WARN("failed to print win dist option", K(ret), K(i));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObWindowDistHint::add_win_dist_option(const ObIArray<ObWinFunRawExpr*> &all_win_funcs,
|
||||
const ObIArray<ObWinFunRawExpr*> &cur_win_funcs,
|
||||
const WinDistAlgo algo,
|
||||
const bool is_push_down,
|
||||
const bool use_hash_sort)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<int64_t, 4> win_func_idxs;
|
||||
int64_t idx = OB_INVALID_INDEX;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < cur_win_funcs.count(); ++i) {
|
||||
if (OB_UNLIKELY(!ObOptimizerUtil::find_item(all_win_funcs, cur_win_funcs.at(i), &idx))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to find item", K(ret), K(all_win_funcs), K(cur_win_funcs));
|
||||
} else if (OB_FAIL(win_func_idxs.push_back(idx))) {
|
||||
LOG_WARN("failed to push back", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && add_win_dist_option(win_func_idxs, algo, is_push_down, use_hash_sort)) {
|
||||
LOG_WARN("failed to add win dist option", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObWindowDistHint::add_win_dist_option(const ObIArray<int64_t> &win_func_idxs,
|
||||
const WinDistAlgo algo,
|
||||
const bool is_push_down,
|
||||
const bool use_hash_sort)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t idx = win_dist_options_.count();
|
||||
if (OB_FAIL(win_dist_options_.prepare_allocate(win_dist_options_.count() + 1))) {
|
||||
LOG_WARN("array prepare allocate failed", K(ret));
|
||||
} else {
|
||||
WinDistOption &win_dist_option = win_dist_options_.at(idx);
|
||||
win_dist_option.algo_ = algo;
|
||||
win_dist_option.is_push_down_ = is_push_down;
|
||||
win_dist_option.use_hash_sort_ = use_hash_sort;
|
||||
if (win_dist_option.win_func_idxs_.assign(win_func_idxs)) {
|
||||
LOG_WARN("failed to add win dist option", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObWindowDistHint::WinDistOption::print_win_dist_option(PlanText &plan_text) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
char *buf = plan_text.buf_;
|
||||
int64_t &buf_len = plan_text.buf_len_;
|
||||
int64_t &pos = plan_text.pos_;
|
||||
if (OB_UNLIKELY(!is_valid())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid WinDistOption", K(ret), K(*this));
|
||||
} else if (win_func_idxs_.empty()) {
|
||||
/* do nothing */
|
||||
} else if (OB_FAIL(BUF_PRINTF(" (%ld", win_func_idxs_.at(0)))) {
|
||||
LOG_WARN("fail to print win func idx", K(ret), K(win_func_idxs_));
|
||||
} else {
|
||||
for (int64_t i = 1; OB_SUCC(ret) && i < win_func_idxs_.count(); ++i) {
|
||||
if (OB_FAIL(BUF_PRINTF(",%ld", win_func_idxs_.at(i)))) {
|
||||
LOG_WARN("fail to print win func idx", K(ret), K(win_func_idxs_));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_FAIL(BUF_PRINTF(")"))) {
|
||||
LOG_WARN("failed to print win func idx", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(BUF_PRINTF(" %s", ObWindowDistHint::get_dist_algo_str(algo_)))) {
|
||||
LOG_WARN("failed to print win func dist algo", K(ret));
|
||||
} else if (use_hash_sort_ && OB_FAIL(BUF_PRINTF(" PARTITION_SORT"))) {
|
||||
LOG_WARN("failed to print win func sort", K(ret));
|
||||
} else if (is_push_down_ && OB_FAIL(BUF_PRINTF(" PUSHDOWN"))) {
|
||||
LOG_WARN("failed to print win func push down", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObWindowDistHint::WinDistOption::is_valid() const
|
||||
{
|
||||
bool bret = true;
|
||||
if (WinDistAlgo::WIN_DIST_INVALID == algo_) {
|
||||
bret = false;
|
||||
} else if (WinDistAlgo::WIN_DIST_HASH != algo_ && is_push_down_) {
|
||||
bret = false;
|
||||
} else if (WinDistAlgo::WIN_DIST_HASH != algo_ && WinDistAlgo::WIN_DIST_NONE != algo_ && use_hash_sort_) {
|
||||
bret = false;
|
||||
} else {
|
||||
for (int64_t i = 0; bret && i < win_func_idxs_.count(); ++i) {
|
||||
bret = win_func_idxs_.at(i) >= 0;
|
||||
}
|
||||
}
|
||||
return bret;
|
||||
}
|
||||
|
||||
int ObWindowDistHint::WinDistOption::assign(const WinDistOption& other)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
algo_ = other.algo_;
|
||||
use_hash_sort_ = other.use_hash_sort_;
|
||||
is_push_down_ = other.is_push_down_;
|
||||
if (OB_FAIL(win_func_idxs_.assign(other.win_func_idxs_))) {
|
||||
LOG_WARN("failed to assign", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObWindowDistHint::WinDistOption::reset()
|
||||
{
|
||||
algo_ = WinDistAlgo::WIN_DIST_INVALID;
|
||||
use_hash_sort_ = false;
|
||||
is_push_down_ = false;
|
||||
win_func_idxs_.reuse();
|
||||
}
|
||||
|
||||
int ObAggHint::assign(const ObAggHint &other)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
Reference in New Issue
Block a user