add pq_gby/pq_distinct hint, fix some outline bug

This commit is contained in:
chimyue 2024-08-21 12:26:57 +00:00 committed by ob-robot
parent cdaf7ee37d
commit 38896ca913
17 changed files with 539 additions and 214 deletions

View File

@ -2588,6 +2588,11 @@ typedef enum ObItemType
//restore sts
T_RESTORE_WITH_CONFIG_LIST = 4732,
T_STS_CREDENTIAL = 4733,
// optimizer hint
T_PQ_GBY_HINT = 4734,
T_PQ_DISTINCT_HINT = 4735,
T_DISTRIBUTE_BASIC = 4736,
T_MAX //Attention: add a new type before T_MAX
} ObItemType;

View File

@ -9758,7 +9758,9 @@ int ObJoinOrder::get_distributed_join_method(Path &left_path,
ObShardingInfo *left_sharding = NULL;
ObShardingInfo *right_sharding = NULL;
distributed_methods = path_info.distributed_methods_;
bool use_shared_hash_join = right_path.parallel_ > ObGlobalHint::DEFAULT_PARALLEL;
const bool is_force_dist_method = !path_info.ignore_hint_
&& (distributed_methods == get_dist_algo(distributed_methods));
bool use_shared_hash_join = false;
ObSQLSessionInfo *session = NULL;
int64_t max_path_parallel = max(left_path.parallel_, right_path.parallel_);
can_slave_mapping =
@ -9773,7 +9775,7 @@ int ObJoinOrder::get_distributed_join_method(Path &left_path,
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(get_plan()), K(left_sharding),
K(right_sharding), K(left_path.parent_), K(ret));
} else if (use_shared_hash_join && OB_FAIL(session->get_px_shared_hash_join( use_shared_hash_join))) {
} else if (OB_FAIL(session->get_px_shared_hash_join(use_shared_hash_join))) {
LOG_WARN("get force parallel ddl dop failed", K(ret));
} else if (HASH_JOIN == join_algo && is_naaj) {
distributed_methods &= ~DIST_PARTITION_WISE;
@ -9791,14 +9793,20 @@ int ObJoinOrder::get_distributed_join_method(Path &left_path,
}
if (OB_SUCC(ret)) {
if (HASH_JOIN == join_algo) {
if (use_shared_hash_join) {
distributed_methods &= ~DIST_BROADCAST_NONE;
distributed_methods &= ~DIST_ALL_NONE;
OPT_TRACE("shared hash join will not use BROADCAST");
if (use_shared_hash_join && right_path.parallel_ > ObGlobalHint::DEFAULT_PARALLEL) {
if (is_force_dist_method && (DIST_BROADCAST_NONE == distributed_methods
|| DIST_ALL_NONE == distributed_methods)) {
/* do nothing */
} else {
distributed_methods &= ~DIST_BROADCAST_NONE;
distributed_methods &= ~DIST_ALL_NONE;
OPT_TRACE("shared hash join will not use BROADCAST");
}
if (IS_LEFT_STYLE_JOIN(path_info.join_type_)) {
distributed_methods &= ~DIST_BC2HOST_NONE;
}
} else {
use_shared_hash_join = false;
distributed_methods &= ~DIST_BC2HOST_NONE;
OPT_TRACE("hash join will not use BC2HOST");
}

View File

@ -348,6 +348,13 @@ int ObLogDistinct::print_outline_data(PlanText &plan_text)
qb_name.length(),
qb_name.ptr()))) {
LOG_WARN("fail to print buffer", K(ret), K(buf), K(buf_len), K(pos));
} else if (NULL != op || is_partition_wise()) {
ObPQHint pq_hint(T_PQ_DISTINCT_HINT);
pq_hint.set_qb_name(qb_name);
pq_hint.set_dist_method(is_partition_wise() ? T_DISTRIBUTE_NONE : T_DISTRIBUTE_HASH);
if (OB_FAIL(pq_hint.print_hint(plan_text))) {
LOG_WARN("failed to print pq hint", K(ret), K(pq_hint));
}
} else {/*do nothing*/}
return ret;
}
@ -362,7 +369,8 @@ int ObLogDistinct::print_used_hint(PlanText &plan_text)
LOG_WARN("unexpected NULL", K(ret), K(get_plan()));
} else {
const ObHint *use_hash = get_plan()->get_log_plan_hint().get_normal_hint(T_USE_HASH_DISTINCT);
const ObHint *pushdown = get_plan()->get_log_plan_hint().get_normal_hint(T_DISTINCT_PUSHDOWN);
const ObHint *pushdown_hint = get_plan()->get_log_plan_hint().get_normal_hint(T_DISTINCT_PUSHDOWN);
const ObPQHint *pq_hint = dynamic_cast<const ObPQHint*>(get_plan()->get_log_plan_hint().get_normal_hint(T_PQ_DISTINCT_HINT));
if (NULL != use_hash) {
bool match_hint = (HASH_AGGREGATE == algo_ && use_hash->is_enable_hint())
|| (MERGE_AGGREGATE == algo_ && use_hash->is_disable_hint());
@ -370,7 +378,7 @@ int ObLogDistinct::print_used_hint(PlanText &plan_text)
LOG_WARN("failed to print used hint for group by", K(ret), K(*use_hash));
}
}
if (OB_SUCC(ret) && NULL != pushdown) {
if (OB_SUCC(ret) && (NULL != pushdown_hint || NULL != pq_hint)) {
const ObLogicalOperator *child = NULL;
const ObLogicalOperator *op = NULL;
if (OB_ISNULL(child = get_child(ObLogicalOperator::first_child))) {
@ -378,12 +386,14 @@ int ObLogDistinct::print_used_hint(PlanText &plan_text)
LOG_WARN("unexpected NULL", K(ret), K(child));
} else if (OB_FAIL(child->get_pushdown_op(log_op_def::LOG_DISTINCT, op))) {
LOG_WARN("failed to get push down distinct", K(ret));
} else {
bool match_hint = NULL == op ? pushdown->is_disable_hint()
: pushdown->is_enable_hint();
if (match_hint && OB_FAIL(pushdown->print_hint(plan_text))) {
LOG_WARN("failed to print used hint for group by", K(ret), K(*pushdown));
}
} else if (NULL != pushdown_hint && (NULL == op ? pushdown_hint->is_disable_hint() : pushdown_hint->is_enable_hint())
&& OB_FAIL(pushdown_hint->print_hint(plan_text))) {
LOG_WARN("failed to print used hint for group by", K(ret), KPC(pushdown_hint));
} else if (NULL != pq_hint
&& ((NULL != op && pq_hint->is_force_dist_hash())
|| (is_partition_wise() && pq_hint->is_force_partition_wise()))
&& OB_FAIL(pq_hint->print_hint(plan_text))) {
LOG_WARN("failed to print used hint for pq group by", K(ret), KPC(pq_hint));
}
}
}

View File

@ -532,6 +532,14 @@ int ObLogGroupBy::print_outline_data(PlanText &plan_text)
LOG_WARN("failed to print hint", K(ret), K(hint));
}
}
if (OB_SUCC(ret) && T_DISTRIBUTE_BASIC != dist_method_) {
ObPQHint hint(T_PQ_GBY_HINT);
hint.set_qb_name(qb_name);
hint.set_dist_method(dist_method_);
if (OB_FAIL(hint.print_hint(plan_text))) {
LOG_WARN("failed to print hint", K(ret), K(hint));
}
}
}
return ret;
}
@ -554,6 +562,10 @@ int ObLogGroupBy::print_used_hint(PlanText &plan_text)
&& static_cast<const ObAggHint*>(hint)->force_partition_sort() == use_part_sort_
&& OB_FAIL(hint->print_hint(plan_text))) {
LOG_WARN("failed to print used hint for group by", K(ret), K(*hint));
} else if (NULL != (hint = get_plan()->get_log_plan_hint().get_normal_hint(T_PQ_GBY_HINT))
&& static_cast<const ObPQHint*>(hint)->is_dist_method_match(dist_method_)
&& OB_FAIL(hint->print_hint(plan_text))) {
LOG_WARN("failed to print used hint for group by", K(ret), K(*hint));
}
return ret;
}

View File

@ -99,6 +99,7 @@ public:
use_hash_aggr_(false),
has_push_down_(false),
use_part_sort_(false),
dist_method_(T_INVALID),
is_pushdown_scalar_aggr_(false)
{}
virtual ~ObLogGroupBy()
@ -218,8 +219,17 @@ public:
{ return ObRollupStatus::ROLLUP_COLLECTOR == rollup_adaptive_info_.rollup_status_; }
inline void set_force_push_down(bool force_push_down)
{ force_push_down_ = force_push_down; }
void set_group_by_outline_info(bool use_hash_aggr, bool has_push_down, bool use_part_sort = false)
{ use_hash_aggr_ = use_hash_aggr; has_push_down_ = has_push_down; use_part_sort_ = use_part_sort; }
void set_group_by_outline_info(bool is_basic,
bool is_partition_wise,
bool use_hash_aggr,
bool has_push_down,
bool use_part_sort = false)
{
dist_method_ = is_basic ? T_DISTRIBUTE_BASIC : (is_partition_wise ? T_DISTRIBUTE_NONE : T_DISTRIBUTE_HASH);
use_hash_aggr_ = use_hash_aggr;
has_push_down_ = has_push_down;
use_part_sort_ = use_part_sort;
}
virtual int get_plan_item_info(PlanText &plan_text,
ObSqlPlanItem &plan_item) override;
@ -265,6 +275,7 @@ private:
bool use_hash_aggr_;
bool has_push_down_;
bool use_part_sort_;
ObItemType dist_method_;
bool is_pushdown_scalar_aggr_;
};
} // end of namespace sql

View File

@ -5201,7 +5201,7 @@ int ObLogPlan::create_three_stage_group_plan(const ObIArray<ObRawExpr*> &group_b
helper.rollup_id_expr_))) {
LOG_WARN("failed to set rollup parallel info", K(ret));
} else {
third_group_by->set_group_by_outline_info(HASH_AGGREGATE == second_aggr_algo, true);
third_group_by->set_group_by_outline_info(false, false, HASH_AGGREGATE == second_aggr_algo, true);
}
}
return ret;
@ -5353,36 +5353,70 @@ int ObLogPlan::candi_allocate_scala_group_by(const ObIArray<ObAggFunRawExpr*> &a
const bool is_from_povit)
{
int ret = OB_SUCCESS;
ObSEArray<CandidatePlan, 4> best_plans;
ObSEArray<CandidatePlan, 4> groupby_plans;
ObSEArray<ObRawExpr*, 1> dummy_exprs;
SMART_VAR(GroupingOpHelper, groupby_helper) {
if (OB_FAIL(init_groupby_helper(dummy_exprs, dummy_exprs, agg_items,
is_from_povit, groupby_helper))) {
LOG_WARN("failed to init group by helper", K(ret));
} else if (OB_FAIL(get_minimal_cost_candidates(candidates_.candidate_plans_, best_plans))) {
LOG_WARN("failed to get minimal cost candidate", K(ret));
} else if (OB_FAIL(inner_candi_allocate_scala_group_by(agg_items,
having_exprs,
groupby_helper,
groupby_plans))) {
LOG_WARN("failed to inner candi allocate scala group by", K(ret));
} else if (!groupby_plans.empty()) {
LOG_TRACE("succeed to allocate scala group by using hint", K(groupby_plans.count()), K(groupby_helper));
OPT_TRACE("success to generate scala group plan with hint");
} else if (OB_FAIL(get_log_plan_hint().check_status())) {
LOG_WARN("failed to generate plans with hint", K(ret));
} else if (OB_FALSE_IT(groupby_helper.set_ignore_hint())) {
} else if (OB_FAIL(inner_candi_allocate_scala_group_by(agg_items,
having_exprs,
groupby_helper,
groupby_plans))) {
LOG_WARN("failed to inner candi allocate scala group by", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < best_plans.count(); i++) {
OPT_TRACE("generate scala group by for plan:", best_plans.at(i));
if (OB_FAIL(create_scala_group_plan(agg_items,
having_exprs,
is_from_povit,
groupby_helper,
best_plans.at(i).plan_tree_))) {
LOG_WARN("failed to create scala group by plan", K(ret));
} else { /*do nothing*/ }
}
if (OB_SUCC(ret)) {
int64_t check_scope = OrderingCheckScope::CHECK_WINFUNC |
OrderingCheckScope::CHECK_DISTINCT |
OrderingCheckScope::CHECK_SET |
OrderingCheckScope::CHECK_ORDERBY;
if (OB_FAIL(update_plans_interesting_order_info(best_plans, check_scope))) {
LOG_WARN("failed to update plans interesting order info", K(ret));
} else if (OB_FAIL(prune_and_keep_best_plans(best_plans))) {
LOG_WARN("failed to add plan", K(ret));
} else { /*do nothing*/ }
}
LOG_TRACE("succeed to allocate scala group by ignore hint", K(groupby_plans.count()), K(groupby_helper));
OPT_TRACE("success to generate scala group plan without hint");
}
if (OB_SUCC(ret)) {
int64_t check_scope = OrderingCheckScope::CHECK_WINFUNC |
OrderingCheckScope::CHECK_DISTINCT |
OrderingCheckScope::CHECK_SET |
OrderingCheckScope::CHECK_ORDERBY;
if (OB_FAIL(update_plans_interesting_order_info(groupby_plans, check_scope))) {
LOG_WARN("failed to update plans interesting order info", K(ret));
} else if (OB_FAIL(prune_and_keep_best_plans(groupby_plans))) {
LOG_WARN("failed to add plan", K(ret));
} else { /*do nothing*/ }
}
}
return ret;
}
int ObLogPlan::inner_candi_allocate_scala_group_by(const ObIArray<ObAggFunRawExpr*> &agg_items,
const ObIArray<ObRawExpr*> &having_exprs,
GroupingOpHelper &groupby_helper,
ObIArray<CandidatePlan> &groupby_plans)
{
int ret = OB_SUCCESS;
ObSEArray<CandidatePlan, 4> best_plans;
if (OB_FAIL(get_minimal_cost_candidates(candidates_.candidate_plans_, best_plans))) {
LOG_WARN("failed to get minimal cost candidate", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < best_plans.count(); i++) {
OPT_TRACE("generate scala group by for plan:", best_plans.at(i));
if (OB_FAIL(create_scala_group_plan(agg_items,
having_exprs,
groupby_helper,
best_plans.at(i).plan_tree_))) {
LOG_WARN("failed to create scala group by plan", K(ret));
} else if (NULL != best_plans.at(i).plan_tree_ &&
OB_FAIL(groupby_plans.push_back(best_plans.at(i)))) {
LOG_WARN("failed to push merge group by", K(ret));
} else { /*do nothing*/ }
}
}
return ret;
@ -5390,7 +5424,6 @@ int ObLogPlan::candi_allocate_scala_group_by(const ObIArray<ObAggFunRawExpr*> &a
int ObLogPlan::create_scala_group_plan(const ObIArray<ObAggFunRawExpr*> &aggr_items,
const ObIArray<ObRawExpr*> &having_exprs,
const bool is_from_povit,
GroupingOpHelper &groupby_helper,
ObLogicalOperator *&top)
{
@ -5411,23 +5444,24 @@ int ObLogPlan::create_scala_group_plan(const ObIArray<ObAggFunRawExpr*> &aggr_it
LOG_WARN("failed to push group by into table scan", K(ret));
} else if (!top->is_distributed()) {
OPT_TRACE("generate scala group plan without pushdown");
if (OB_FAIL(allocate_scala_group_by_as_top(top,
aggr_items,
having_exprs,
is_from_povit,
origin_child_card))) {
if (!groupby_helper.allow_basic()) {
top = NULL;
OPT_TRACE("ignore basic scala group by hint");
} else if (OB_FAIL(allocate_scala_group_by_as_top(top,
aggr_items,
having_exprs,
groupby_helper.is_from_povit_,
origin_child_card))) {
LOG_WARN("failed to allocate scala group by as top", K(ret));
} else {
static_cast<ObLogGroupBy*>(top)->set_group_by_outline_info(false, false);
static_cast<ObLogGroupBy*>(top)->set_group_by_outline_info(true, false, false, false);
}
} else if (!groupby_helper.distinct_exprs_.empty() &&
OB_FAIL(top->check_sharding_compatible_with_reduce_expr(groupby_helper.distinct_exprs_,
is_partition_wise))) {
LOG_WARN("failed to check if sharding compatible with distinct expr", K(ret));
} else if (groupby_helper.can_three_stage_pushdown_ &&
!(is_partition_wise &&
!(top->is_parallel_more_than_part_cnt() &&
get_optimizer_context().get_query_ctx()->optimizer_features_enable_version_ > COMPAT_VERSION_4_3_2))) {
!(is_partition_wise && groupby_helper.allow_partition_wise(top->is_parallel_more_than_part_cnt()))) {
OPT_TRACE("generate three stage group plan");
if (NULL == groupby_helper.aggr_code_expr_ &&
OB_FAIL(prepare_three_stage_info(dummy_exprs, dummy_exprs, groupby_helper))) {
@ -5447,7 +5481,7 @@ int ObLogPlan::create_scala_group_plan(const ObIArray<ObAggFunRawExpr*> &aggr_it
dummy_exprs,
aggr_items,
dummy_exprs,
is_from_povit,
groupby_helper.is_from_povit_,
groupby_helper.group_ndv_,
origin_child_card,
is_partition_wise,
@ -5461,11 +5495,11 @@ int ObLogPlan::create_scala_group_plan(const ObIArray<ObAggFunRawExpr*> &aggr_it
} else if (OB_FAIL(allocate_scala_group_by_as_top(top,
aggr_items,
having_exprs,
is_from_povit,
groupby_helper.is_from_povit_,
origin_child_card))) {
LOG_WARN("failed to allocate scala group by as top", K(ret));
} else {
static_cast<ObLogGroupBy*>(top)->set_group_by_outline_info(false, groupby_helper.can_basic_pushdown_ || is_partition_wise);
static_cast<ObLogGroupBy*>(top)->set_group_by_outline_info(false, is_partition_wise, false, groupby_helper.can_basic_pushdown_ || is_partition_wise);
}
}
@ -5576,6 +5610,9 @@ int ObLogPlan::init_groupby_helper(const ObIArray<ObRawExpr*> &group_exprs,
ObSEArray<ObRawExpr*, 4> group_rollup_exprs;
bool push_group = false;
groupby_helper.is_scalar_group_by_ = true;
groupby_helper.is_from_povit_ = is_from_povit;
groupby_helper.clear_ignore_hint();
groupby_helper.optimizer_features_enable_version_ = get_log_plan_hint().optimizer_features_enable_version_;
if (OB_FAIL(candidates_.get_best_plan(best_plan))) {
LOG_WARN("failed to get best plan", K(ret));
} else if (OB_ISNULL(best_plan) ||
@ -5591,7 +5628,10 @@ int ObLogPlan::init_groupby_helper(const ObIArray<ObRawExpr*> &group_exprs,
} else if (OB_FAIL(get_log_plan_hint().get_aggregation_info(groupby_helper.force_use_hash_,
groupby_helper.force_use_merge_,
groupby_helper.force_part_sort_,
groupby_helper.force_normal_sort_))) {
groupby_helper.force_normal_sort_,
groupby_helper.force_basic_,
groupby_helper.force_partition_wise_,
groupby_helper.force_dist_hash_))) {
LOG_WARN("failed to get aggregation info from hint", K(ret));
} else if (OB_FAIL(check_storage_groupby_pushdown(aggr_items,
group_exprs,
@ -5696,18 +5736,24 @@ int ObLogPlan::init_distinct_helper(const ObIArray<ObRawExpr*> &distinct_exprs,
ObSQLSessionInfo *session_info = NULL;
bool push_distinct = false;
distinct_helper.can_basic_pushdown_ = false;
distinct_helper.force_use_hash_ = get_log_plan_hint().use_hash_distinct();
distinct_helper.force_use_merge_ = get_log_plan_hint().use_merge_distinct();
distinct_helper.clear_ignore_hint();
distinct_helper.optimizer_features_enable_version_ = get_log_plan_hint().optimizer_features_enable_version_;
if (OB_FAIL(candidates_.get_best_plan(best_plan))) {
LOG_WARN("failed to get best plan", K(ret));
} else if (OB_ISNULL(best_plan) || OB_ISNULL(get_stmt())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (get_log_plan_hint().no_pushdown_distinct()) {
OPT_TRACE("hint disable pushdown distinct");
} else if (OB_FAIL(get_log_plan_hint().get_distinct_info(distinct_helper.force_use_hash_,
distinct_helper.force_use_merge_,
distinct_helper.force_basic_,
distinct_helper.force_partition_wise_,
distinct_helper.force_dist_hash_))) {
LOG_WARN("failed to get distinct info from hint", K(ret));
} else if (OB_FAIL(check_storage_distinct_pushdown(distinct_exprs,
distinct_helper.can_storage_pushdown_))) {
LOG_WARN("failed to check can storage distinct pushdown", K(ret));
} else if (get_log_plan_hint().no_pushdown_distinct()) {
OPT_TRACE("hint disable pushdown distinct");
} else if (OB_ISNULL(session_info = get_optimizer_context().get_session_info())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(session_info), K(ret));

View File

@ -485,6 +485,17 @@ public:
}
virtual ~GroupingOpHelper() {}
void set_ignore_hint() { ignore_hint_ = true; }
void clear_ignore_hint() { ignore_hint_ = false; }
inline bool allow_basic() const { return ignore_hint_ || (!force_partition_wise_ && !force_dist_hash_); }
inline bool allow_dist_hash() const { return ignore_hint_ || (!force_basic_ && !force_partition_wise_); }
inline bool allow_partition_wise(bool parallel_more_than_part_cnt) const
{
bool disable_by_rule = parallel_more_than_part_cnt && optimizer_features_enable_version_ > COMPAT_VERSION_4_3_2;
return ignore_hint_ ? !disable_by_rule
: (disable_by_rule ? force_partition_wise_ : (!force_basic_ && !force_dist_hash_));
}
bool can_storage_pushdown_;
bool can_basic_pushdown_;
bool can_three_stage_pushdown_;
@ -493,7 +504,13 @@ public:
bool force_use_merge_; // has no_use_hash_aggregation/no_use_hash_distinct hint
bool force_part_sort_; // force use partition sort for merge group by
bool force_normal_sort_; // disable use partition sort for merge group by
bool force_basic_; // pq hint force use basic plan
bool force_partition_wise_; // pq hint force use partition wise plan
bool force_dist_hash_; // pq hint force use hash distributed method plan
bool is_scalar_group_by_;
bool is_from_povit_;
bool ignore_hint_;
uint64_t optimizer_features_enable_version_;
ObSEArray<ObRawExpr*, 8> distinct_exprs_;
// context for three stage group by push down
@ -518,7 +535,15 @@ public:
K_(can_rollup_pushdown),
K_(force_use_hash),
K_(force_use_merge),
K_(force_part_sort),
K_(force_normal_sort),
K_(force_basic),
K_(force_partition_wise),
K_(force_dist_hash),
K_(is_scalar_group_by),
K_(is_from_povit),
K_(ignore_hint),
K_(optimizer_features_enable_version),
K_(distinct_exprs),
K_(pushdown_groupby_columns),
K_(group_ndv),
@ -675,6 +700,11 @@ public:
const ObIArray<ObRawExpr*> &having_exprs,
const bool is_from_povit);
int inner_candi_allocate_scala_group_by(const ObIArray<ObAggFunRawExpr*> &agg_items,
const ObIArray<ObRawExpr*> &having_exprs,
GroupingOpHelper &groupby_helper,
ObIArray<CandidatePlan> &groupby_plans);
int prepare_three_stage_info(const ObIArray<ObRawExpr *> &group_by_exprs,
const ObIArray<ObRawExpr *> &rollup_exprs,
GroupingOpHelper &helper);
@ -712,7 +742,6 @@ public:
int create_scala_group_plan(const ObIArray<ObAggFunRawExpr*> &agg_items,
const ObIArray<ObRawExpr*> &having_exprs,
const bool is_from_povit,
GroupingOpHelper &groupby_helper,
ObLogicalOperator *&top);

View File

@ -265,10 +265,28 @@ int ObSelectLogPlan::candi_allocate_normal_group_by(const ObIArray<ObRawExpr*> &
rollup_directions,
aggr_items,
having_exprs,
is_from_povit,
groupby_helper,
groupby_plans))) {
LOG_WARN("failed to candi allocate three stage group by", K(ret));
} else if (!groupby_plans.empty()) {
LOG_TRACE("succeed to allocate three stage group by using hint", K(groupby_plans.count()), K(groupby_helper));
OPT_TRACE("success to generate three stage group plan with hint");
} else if (OB_FAIL(get_log_plan_hint().check_status())) {
LOG_WARN("failed to generate plans with hint", K(ret));
} else if (OB_FALSE_IT(groupby_helper.set_ignore_hint())) {
} else if (OB_FAIL(candi_allocate_three_stage_group_by(reduce_exprs,
group_by_exprs,
group_directions,
rollup_exprs,
rollup_directions,
aggr_items,
having_exprs,
groupby_helper,
groupby_plans))) {
LOG_WARN("failed to candi allocate three stage group by", K(ret));
} else {
LOG_TRACE("succeed to allocate three stage group by ignore hint", K(groupby_plans.count()), K(groupby_helper));
OPT_TRACE("success to generate three stage group plan without hint");
}
} else if (OB_FAIL(candi_allocate_normal_group_by(reduce_exprs,
group_by_exprs,
@ -277,9 +295,7 @@ int ObSelectLogPlan::candi_allocate_normal_group_by(const ObIArray<ObRawExpr*> &
rollup_directions,
having_exprs,
aggr_items,
is_from_povit,
groupby_helper,
false,
groupby_plans))) {
LOG_WARN("failed to inner allocate normal group by", K(ret));
} else if (!groupby_plans.empty()) {
@ -287,6 +303,7 @@ int ObSelectLogPlan::candi_allocate_normal_group_by(const ObIArray<ObRawExpr*> &
OPT_TRACE("success to generate group plan with hint");
} else if (OB_FAIL(get_log_plan_hint().check_status())) {
LOG_WARN("failed to generate plans with hint", K(ret));
} else if (OB_FALSE_IT(groupby_helper.set_ignore_hint())) {
} else if (OB_FAIL(candi_allocate_normal_group_by(reduce_exprs,
group_by_exprs,
group_directions,
@ -294,9 +311,7 @@ int ObSelectLogPlan::candi_allocate_normal_group_by(const ObIArray<ObRawExpr*> &
rollup_directions,
having_exprs,
aggr_items,
is_from_povit,
groupby_helper,
true,
groupby_plans))) {
LOG_WARN("failed to inner allocate normal group by", K(ret));
} else {
@ -328,7 +343,6 @@ int ObSelectLogPlan::candi_allocate_three_stage_group_by(const ObIArray<ObRawExp
const ObIArray<ObOrderDirection> &rollup_directions,
const ObIArray<ObAggFunRawExpr*> &aggr_items,
const ObIArray<ObRawExpr*> &having_exprs,
const bool is_from_povit,
GroupingOpHelper &groupby_helper,
ObIArray<CandidatePlan> &groupby_plans)
{
@ -344,14 +358,13 @@ int ObSelectLogPlan::candi_allocate_three_stage_group_by(const ObIArray<ObRawExp
if (OB_ISNULL(candidate_plan.plan_tree_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (candidate_plan.plan_tree_->is_distributed() && !reduce_exprs.empty() &&
OB_FAIL(candidate_plan.plan_tree_->check_sharding_compatible_with_reduce_expr(reduce_exprs,
is_partition_wise))) {
} else if (!candidate_plan.plan_tree_->is_distributed() && !groupby_helper.allow_basic()) {
OPT_TRACE("ignore basic group by hint");
} else if (candidate_plan.plan_tree_->is_distributed() && !reduce_exprs.empty()
&& groupby_helper.allow_partition_wise(candidate_plan.plan_tree_->is_parallel_more_than_part_cnt())
&& OB_FAIL(candidate_plan.plan_tree_->check_sharding_compatible_with_reduce_expr(reduce_exprs, is_partition_wise))) {
LOG_WARN("failed to check if sharding compatible with distinct expr", K(ret));
} else if (!candidate_plan.plan_tree_->is_distributed() ||
(is_partition_wise &&
!(candidate_plan.plan_tree_->is_parallel_more_than_part_cnt() &&
get_optimizer_context().get_query_ctx()->optimizer_features_enable_version_ > COMPAT_VERSION_4_3_2))) {
} else if (!candidate_plan.plan_tree_->is_distributed() || is_partition_wise) {
bool part_sort_valid = !groupby_helper.force_normal_sort_ && !group_by_exprs.empty();
bool normal_sort_valid = !groupby_helper.force_part_sort_;
if (OB_FAIL(update_part_sort_method(part_sort_valid, normal_sort_valid))) {
@ -363,7 +376,6 @@ int ObSelectLogPlan::candi_allocate_three_stage_group_by(const ObIArray<ObRawExp
rollup_directions,
aggr_items,
having_exprs,
is_from_povit,
groupby_helper,
candidate_plan,
groupby_plans,
@ -393,7 +405,6 @@ int ObSelectLogPlan::candi_allocate_three_stage_group_by(const ObIArray<ObRawExp
int ObSelectLogPlan::get_valid_aggr_algo(const ObIArray<ObRawExpr*> &group_by_exprs,
const GroupingOpHelper &groupby_helper,
const bool ignore_hint,
bool &use_hash_valid,
bool &use_merge_valid,
bool &part_sort_valid,
@ -401,7 +412,7 @@ int ObSelectLogPlan::get_valid_aggr_algo(const ObIArray<ObRawExpr*> &group_by_ex
{
int ret = OB_SUCCESS;
bool has_keep_aggr = false;
if (ignore_hint) {
if (groupby_helper.ignore_hint_) {
use_hash_valid = true;
use_merge_valid = true;
part_sort_valid = true;
@ -470,9 +481,7 @@ int ObSelectLogPlan::candi_allocate_normal_group_by(const ObIArray<ObRawExpr*> &
const ObIArray<ObOrderDirection> &rollup_directions,
const ObIArray<ObRawExpr*> &having_exprs,
const ObIArray<ObAggFunRawExpr*> &aggr_items,
const bool is_from_povit,
GroupingOpHelper &groupby_helper,
const bool ignore_hint,
ObIArray<CandidatePlan> &groupby_plans)
{
int ret = OB_SUCCESS;
@ -481,7 +490,7 @@ int ObSelectLogPlan::candi_allocate_normal_group_by(const ObIArray<ObRawExpr*> &
bool use_merge_valid = false;
bool part_sort_valid = false;
bool normal_sort_valid = false;
if (OB_FAIL(get_valid_aggr_algo(group_by_exprs, groupby_helper, ignore_hint,
if (OB_FAIL(get_valid_aggr_algo(group_by_exprs, groupby_helper,
use_hash_valid, use_merge_valid,
part_sort_valid, normal_sort_valid))) {
LOG_WARN("failed to get valid aggr algo", K(ret));
@ -500,7 +509,6 @@ int ObSelectLogPlan::candi_allocate_normal_group_by(const ObIArray<ObRawExpr*> &
rollup_exprs,
aggr_items,
having_exprs,
is_from_povit,
groupby_helper,
candidate_plan.plan_tree_))) {
LOG_WARN("failed to create hash group by plan", K(ret));
@ -543,7 +551,6 @@ int ObSelectLogPlan::candi_allocate_normal_group_by(const ObIArray<ObRawExpr*> &
rollup_directions,
aggr_items,
having_exprs,
is_from_povit,
groupby_helper,
candidate_plan,
groupby_plans,
@ -572,13 +579,13 @@ int ObSelectLogPlan::should_create_rollup_pushdown_plan(ObLogicalOperator *top,
LOG_WARN("logical operator is null", K(ret), K(top), K(session));
} else if (rollup_exprs.empty() || !groupby_helper.can_rollup_pushdown_) {
// do nothing
} else if (top->is_distributed() &&
OB_FAIL(top->check_sharding_compatible_with_reduce_expr(reduce_exprs,
is_partition_wise))) {
} else if (!top->is_distributed() && !groupby_helper.allow_basic()) {
// do nothing
} else if (top->is_distributed() && groupby_helper.allow_partition_wise(top->is_parallel_more_than_part_cnt())
&& OB_FAIL(top->check_sharding_compatible_with_reduce_expr(reduce_exprs,
is_partition_wise))) {
LOG_WARN("failed to check is partition wise", K(ret));
} else if (!top->is_distributed() || (is_partition_wise &&
!(top->is_parallel_more_than_part_cnt() &&
get_optimizer_context().get_query_ctx()->optimizer_features_enable_version_ > COMPAT_VERSION_4_3_2))) {
} else if (!top->is_distributed() || is_partition_wise) {
// do nothing
} else if (NULL == groupby_helper.rollup_id_expr_ &&
OB_FAIL(ObRawExprUtils::build_pseudo_rollup_id(get_optimizer_context().get_expr_factory(),
@ -715,7 +722,7 @@ int ObSelectLogPlan::create_rollup_pushdown_plan(const ObIArray<ObRawExpr*> &gro
groupby_helper.rollup_id_expr_))) {
LOG_WARN("failed to set rollup id expr", K(ret));
} else {
rollup_collector->set_group_by_outline_info(false, true);
rollup_collector->set_group_by_outline_info(false, false, false, true);
}
return ret;
}
@ -725,7 +732,6 @@ int ObSelectLogPlan::create_hash_group_plan(const ObIArray<ObRawExpr*> &reduce_e
const ObIArray<ObRawExpr*> &rollup_exprs,
const ObIArray<ObAggFunRawExpr*> &aggr_items,
const ObIArray<ObRawExpr*> &having_exprs,
const bool is_from_povit,
GroupingOpHelper &groupby_helper,
ObLogicalOperator *&top)
{
@ -736,26 +742,28 @@ int ObSelectLogPlan::create_hash_group_plan(const ObIArray<ObRawExpr*> &reduce_e
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(top), K(get_stmt()), K(ret));
} else if (OB_FALSE_IT(origin_child_card = top->get_card())) {
} else if (top->is_distributed() &&
OB_FAIL(top->check_sharding_compatible_with_reduce_expr(reduce_exprs,
is_partition_wise))) {
} else if (!top->is_distributed() && !groupby_helper.allow_basic()) {
top = NULL;
OPT_TRACE("ignore basic hash group by hint");
} else if (top->is_distributed() && groupby_helper.allow_partition_wise(top->is_parallel_more_than_part_cnt())
&& OB_FAIL(top->check_sharding_compatible_with_reduce_expr(reduce_exprs,
is_partition_wise))) {
LOG_WARN("failed to check if sharding compatible", K(ret));
} else if (!top->is_distributed() || (is_partition_wise &&
!(top->is_parallel_more_than_part_cnt() &&
get_optimizer_context().get_query_ctx()->optimizer_features_enable_version_ > COMPAT_VERSION_4_3_2))) {
} else if (!top->is_distributed() || is_partition_wise) {
bool is_basic = !top->is_distributed();
if (OB_FAIL(allocate_group_by_as_top(top,
AggregateAlgo::HASH_AGGREGATE,
group_by_exprs,
rollup_exprs,
aggr_items,
having_exprs,
is_from_povit,
groupby_helper.is_from_povit_,
groupby_helper.group_ndv_,
origin_child_card,
is_partition_wise))) {
LOG_WARN("failed to allocate group by as top", K(ret));
} else {
static_cast<ObLogGroupBy*>(top)->set_group_by_outline_info(true, false);
static_cast<ObLogGroupBy*>(top)->set_group_by_outline_info(is_basic, is_partition_wise, true, false);
}
} else {
// allocate push down group by
@ -776,7 +784,7 @@ int ObSelectLogPlan::create_hash_group_plan(const ObIArray<ObRawExpr*> &reduce_e
dummy_exprs,
aggr_items,
dummy_exprs,
is_from_povit,
groupby_helper.is_from_povit_,
groupby_helper.group_ndv_,
origin_child_card,
is_partition_wise,
@ -807,12 +815,12 @@ int ObSelectLogPlan::create_hash_group_plan(const ObIArray<ObRawExpr*> &reduce_e
rollup_exprs,
aggr_items,
having_exprs,
is_from_povit,
groupby_helper.is_from_povit_,
groupby_helper.group_ndv_,
origin_child_card))) {
LOG_WARN("failed to allocate scala group by as top", K(ret));
} else {
static_cast<ObLogGroupBy*>(top)->set_group_by_outline_info(true, groupby_helper.can_basic_pushdown_);
static_cast<ObLogGroupBy*>(top)->set_group_by_outline_info(false, false, true, groupby_helper.can_basic_pushdown_);
}
}
}
@ -955,7 +963,6 @@ int ObSelectLogPlan::create_merge_group_plan(const ObIArray<ObRawExpr*> &reduce_
const ObIArray<ObOrderDirection> &rollup_directions,
const ObIArray<ObAggFunRawExpr*> &aggr_items,
const ObIArray<ObRawExpr*> &having_exprs,
const bool is_from_povit,
GroupingOpHelper &groupby_helper,
CandidatePlan &candidate_plan,
ObIArray<CandidatePlan> &candidate_plans,
@ -973,7 +980,6 @@ int ObSelectLogPlan::create_merge_group_plan(const ObIArray<ObRawExpr*> &reduce_
rollup_directions,
aggr_items,
having_exprs,
is_from_povit,
groupby_helper,
part_sort_mgb_plan.plan_tree_,
true,
@ -990,7 +996,6 @@ int ObSelectLogPlan::create_merge_group_plan(const ObIArray<ObRawExpr*> &reduce_
rollup_directions,
aggr_items,
having_exprs,
is_from_povit,
groupby_helper,
candidate_plan.plan_tree_,
false,
@ -1010,7 +1015,6 @@ int ObSelectLogPlan::inner_create_merge_group_plan(const ObIArray<ObRawExpr*> &r
const ObIArray<ObOrderDirection> &rollup_directions,
const ObIArray<ObAggFunRawExpr*> &aggr_items,
const ObIArray<ObRawExpr*> &having_exprs,
const bool is_from_povit,
GroupingOpHelper &groupby_helper,
ObLogicalOperator *&top,
bool use_part_sort,
@ -1086,13 +1090,15 @@ int ObSelectLogPlan::inner_create_merge_group_plan(const ObIArray<ObRawExpr*> &r
// 1. need generate partition sort plan, but need not sort
// 2. if need sort and no further op needs the output order, not generate merge groupby
top = NULL;
} else if (top->is_distributed() &&
OB_FAIL(top->check_sharding_compatible_with_reduce_expr(reduce_exprs,
is_partition_wise))) {
} else if (!top->is_distributed() && !groupby_helper.allow_basic()) {
top = NULL;
OPT_TRACE("ignore basic group by hint");
} else if (top->is_distributed() && groupby_helper.allow_partition_wise(top->is_parallel_more_than_part_cnt())
&& OB_FAIL(top->check_sharding_compatible_with_reduce_expr(reduce_exprs,
is_partition_wise))) {
LOG_WARN("failed to check if sharding compatible with reduce expr", K(ret));
} else if (!top->is_distributed() || (is_partition_wise &&
!(top->is_parallel_more_than_part_cnt() &&
get_optimizer_context().get_query_ctx()->optimizer_features_enable_version_ > COMPAT_VERSION_4_3_2))) {
} else if (!top->is_distributed() || is_partition_wise) {
bool is_basic = !top->is_distributed();
if (OB_FAIL(try_allocate_sort_as_top(top, sort_keys, need_sort, prefix_pos, part_cnt))) {
LOG_WARN("failed to allocate sort as top", K(ret));
} else if (OB_FAIL(allocate_group_by_as_top(top,
@ -1101,13 +1107,13 @@ int ObSelectLogPlan::inner_create_merge_group_plan(const ObIArray<ObRawExpr*> &r
rollup_exprs,
aggr_items,
having_exprs,
is_from_povit,
groupby_helper.is_from_povit_,
groupby_helper.group_ndv_,
origin_child_card,
is_partition_wise))) {
LOG_WARN("failed to allocate group by as top", K(ret));
} else {
static_cast<ObLogGroupBy*>(top)->set_group_by_outline_info(false, false, use_part_sort);
static_cast<ObLogGroupBy*>(top)->set_group_by_outline_info(is_basic, is_partition_wise, false, false, use_part_sort);
}
} else if (use_part_sort &&
OB_FAIL(create_hash_sortkey(part_cnt, sort_keys, hash_sortkey))) {
@ -1149,7 +1155,7 @@ int ObSelectLogPlan::inner_create_merge_group_plan(const ObIArray<ObRawExpr*> &r
dummy_exprs,
aggr_items,
dummy_exprs,
is_from_povit,
groupby_helper.is_from_povit_,
groupby_helper.group_ndv_,
origin_child_card,
should_pullup_gi,
@ -1187,12 +1193,12 @@ int ObSelectLogPlan::inner_create_merge_group_plan(const ObIArray<ObRawExpr*> &r
rollup_exprs,
aggr_items,
having_exprs,
is_from_povit,
groupby_helper.is_from_povit_,
groupby_helper.group_ndv_,
origin_child_card))) {
LOG_WARN("failed to allocate group by as top", K(ret));
} else {
static_cast<ObLogGroupBy*>(top)->set_group_by_outline_info(false,
static_cast<ObLogGroupBy*>(top)->set_group_by_outline_info(false, false, false,
groupby_helper.can_basic_pushdown_, use_part_sort);
}
}
@ -1440,63 +1446,37 @@ int ObSelectLogPlan::candi_allocate_distinct()
LOG_TRACE("distinct exprs is unique, no need distinct", K(distinct_exprs));
} else {
SMART_VAR(GroupingOpHelper, distinct_helper) {
CandidatePlan candidate_plan;
ObSEArray<CandidatePlan, 4> distinct_plans;
ObSEArray<ObOrderDirection, 4> distinct_directions;
ObSEArray<ObAggFunRawExpr*, 1> dummy_items;
if (OB_FAIL(init_distinct_helper(distinct_exprs, distinct_helper))) {
LOG_WARN("failed to init distinct helper", K(ret));
} else if (OB_FAIL(ObOptimizerUtil::get_default_directions(distinct_exprs.count(),
distinct_directions))) {
LOG_WARN("failed to generate default directions", K(ret));
} else if (distinct_helper.can_storage_pushdown_ &&
OB_FAIL(try_push_aggr_into_table_scan(candidates_.candidate_plans_,
dummy_items,
distinct_exprs))) {
LOG_WARN("failed to try push distinct exprs into table scan", K(ret));
} else if (OB_FAIL(inner_candi_allocate_distinct(distinct_helper,
reduce_exprs,
distinct_exprs,
distinct_plans))) {
LOG_WARN("failed to inner candi allocate distinct", K(ret));
} else if (!distinct_plans.empty()) {
LOG_TRACE("succeed to allocate distinct using hint", K(distinct_plans.count()), K(distinct_helper));
OPT_TRACE("success to generate distinct plan with hint");
} else if (OB_FAIL(get_log_plan_hint().check_status())) {
LOG_WARN("failed to generate plans with hint", K(ret));
} else if (OB_FALSE_IT(distinct_helper.set_ignore_hint())) {
} else if (OB_FAIL(inner_candi_allocate_distinct(distinct_helper,
reduce_exprs,
distinct_exprs,
distinct_plans))) {
LOG_WARN("failed to inner candi allocate distinct", K(ret));
} else {
LOG_TRACE("succeed to allocate distinct ignore hint", K(distinct_plans.count()), K(distinct_helper));
OPT_TRACE("success to generate distinct plan without hint");
}
// create hash distinct
if (OB_SUCC(ret) && !distinct_helper.force_use_merge_) {
ObSEArray<CandidatePlan, 16> best_candidates;
if (OB_FAIL(get_minimal_cost_candidates(candidates_.candidate_plans_, best_candidates))) {
LOG_WARN("failed to get minimal cost candidates", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < best_candidates.count(); i++) {
candidate_plan = best_candidates.at(i);
OPT_TRACE("generate hash distinct for plan:", candidate_plan);
if (OB_FAIL(create_hash_distinct_plan(candidate_plan.plan_tree_,
distinct_helper,
reduce_exprs,
distinct_exprs))) {
LOG_WARN("failed to create hash distinct plan", K(ret));
} else if (OB_FAIL(distinct_plans.push_back(candidate_plan))) {
LOG_WARN("failed to push back hash distinct candidate plan", K(ret));
} else { /*do nothing*/ }
}
}
}
//create merge distinct plan
if (OB_SUCC(ret) && !distinct_helper.force_use_hash_) {
bool can_ignore_merge_plan = !(distinct_plans.empty() || distinct_helper.force_use_merge_);
bool is_plan_valid = false;
for(int64_t i = 0; OB_SUCC(ret) && i < candidates_.candidate_plans_.count(); i++) {
candidate_plan = candidates_.candidate_plans_.at(i);
OPT_TRACE("generate merge distinct for plan:", candidate_plan);
if (OB_FAIL(create_merge_distinct_plan(candidate_plan.plan_tree_,
distinct_helper,
reduce_exprs,
distinct_exprs,
distinct_directions,
is_plan_valid,
can_ignore_merge_plan))) {
LOG_WARN("failed to allocate merge distinct plan", K(ret));
} else if (is_plan_valid && OB_FAIL(distinct_plans.push_back(candidate_plan))) {
LOG_WARN("failed to add merge distinct candidate plan", K(ret));
} else { /*do nothing*/ }
}
}
if (OB_SUCC(ret)) {
int64_t check_scope = OrderingCheckScope::CHECK_SET | OrderingCheckScope::CHECK_ORDERBY;
if (OB_FAIL(update_plans_interesting_order_info(distinct_plans, check_scope))) {
@ -1510,6 +1490,56 @@ int ObSelectLogPlan::candi_allocate_distinct()
return ret;
}
int ObSelectLogPlan::inner_candi_allocate_distinct(const GroupingOpHelper &distinct_helper,
const ObIArray<ObRawExpr*> &reduce_exprs,
const ObIArray<ObRawExpr*> &distinct_exprs,
ObIArray<CandidatePlan> &distinct_plans)
{
int ret = OB_SUCCESS;
CandidatePlan candidate_plan;
// create hash distinct
if (OB_SUCC(ret) && !distinct_helper.force_use_merge_) {
ObSEArray<CandidatePlan, 16> best_candidates;
if (OB_FAIL(get_minimal_cost_candidates(candidates_.candidate_plans_, best_candidates))) {
LOG_WARN("failed to get minimal cost candidates", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < best_candidates.count(); i++) {
candidate_plan = best_candidates.at(i);
OPT_TRACE("generate hash distinct for plan:", candidate_plan);
if (OB_FAIL(create_hash_distinct_plan(candidate_plan.plan_tree_,
distinct_helper,
reduce_exprs,
distinct_exprs))) {
LOG_WARN("failed to create hash distinct plan", K(ret));
} else if (NULL != candidate_plan.plan_tree_
&& OB_FAIL(distinct_plans.push_back(candidate_plan))) {
LOG_WARN("failed to push back hash distinct candidate plan", K(ret));
} else { /*do nothing*/ }
}
}
}
//create merge distinct plan
if (OB_SUCC(ret) && !distinct_helper.force_use_hash_) {
bool can_ignore_merge_plan = !(distinct_plans.empty() || distinct_helper.force_use_merge_);
for(int64_t i = 0; OB_SUCC(ret) && i < candidates_.candidate_plans_.count(); i++) {
candidate_plan = candidates_.candidate_plans_.at(i);
OPT_TRACE("generate merge distinct for plan:", candidate_plan);
if (OB_FAIL(create_merge_distinct_plan(candidate_plan.plan_tree_,
distinct_helper,
reduce_exprs,
distinct_exprs,
can_ignore_merge_plan))) {
LOG_WARN("failed to allocate merge distinct plan", K(ret));
} else if (NULL != candidate_plan.plan_tree_
&& OB_FAIL(distinct_plans.push_back(candidate_plan))) {
LOG_WARN("failed to add merge distinct candidate plan", K(ret));
} else { /*do nothing*/ }
}
}
return ret;
}
int ObSelectLogPlan::get_distinct_exprs(const ObLogicalOperator *top,
ObIArray<ObRawExpr *> &reduce_exprs,
ObIArray<ObRawExpr *> &distinct_exprs)
@ -1561,9 +1591,9 @@ int ObSelectLogPlan::get_distinct_exprs(const ObLogicalOperator *top,
}
int ObSelectLogPlan::create_hash_distinct_plan(ObLogicalOperator *&top,
GroupingOpHelper &distinct_helper,
ObIArray<ObRawExpr*> &reduce_exprs,
ObIArray<ObRawExpr*> &distinct_exprs)
const GroupingOpHelper &distinct_helper,
const ObIArray<ObRawExpr*> &reduce_exprs,
const ObIArray<ObRawExpr*> &distinct_exprs)
{
int ret = OB_SUCCESS;
bool is_partition_wise = false;
@ -1571,14 +1601,14 @@ int ObSelectLogPlan::create_hash_distinct_plan(ObLogicalOperator *&top,
if (OB_ISNULL(top)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(top), K(ret));
} else if (top->is_distributed() &&
OB_FAIL(top->check_sharding_compatible_with_reduce_expr(reduce_exprs,
is_partition_wise))) {
} else if (!top->is_distributed() && !distinct_helper.allow_basic()) {
top = NULL;
OPT_TRACE("ignore basic distinct by hint");
} else if (top->is_distributed() && distinct_helper.allow_partition_wise(top->is_parallel_more_than_part_cnt())
&& OB_FAIL(top->check_sharding_compatible_with_reduce_expr(reduce_exprs,
is_partition_wise))) {
LOG_WARN("failed to check sharding compatible with reduce expr", K(ret));
} else if (!top->is_distributed() ||
(is_partition_wise &&
!(top->is_parallel_more_than_part_cnt() &&
get_optimizer_context().get_query_ctx()->optimizer_features_enable_version_ > COMPAT_VERSION_4_3_2))) {
} else if (!top->is_distributed() || is_partition_wise) {
OPT_TRACE("is basic distinct:", !top->is_distributed());
OPT_TRACE("is partition wise distinct", is_partition_wise);
if (OB_FAIL(allocate_distinct_as_top(top,
@ -1613,11 +1643,9 @@ int ObSelectLogPlan::create_hash_distinct_plan(ObLogicalOperator *&top,
}
int ObSelectLogPlan::create_merge_distinct_plan(ObLogicalOperator *&top,
GroupingOpHelper &distinct_helper,
ObIArray<ObRawExpr*> &reduce_exprs,
ObIArray<ObRawExpr*> &distinct_exprs,
ObIArray<ObOrderDirection> &directions,
bool &is_plan_valid,
const GroupingOpHelper &distinct_helper,
const ObIArray<ObRawExpr*> &reduce_exprs,
const ObIArray<ObRawExpr*> &in_distinct_exprs,
bool can_ignore_merge_plan)
{
int ret = OB_SUCCESS;
@ -1626,11 +1654,19 @@ int ObSelectLogPlan::create_merge_distinct_plan(ObLogicalOperator *&top,
bool is_partition_wise = false;
ObSEArray<OrderItem, 4> sort_keys;
int64_t interesting_order_info = OrderingFlag::NOT_MATCH;
is_plan_valid = true;
ObSEArray<ObRawExpr*, 4> distinct_exprs;
ObSEArray<ObOrderDirection, 4> directions;
OPT_TRACE("start generate merge distinct plan");
if (OB_ISNULL(top)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (!top->is_distributed() && !distinct_helper.allow_basic()) {
top = NULL;
OPT_TRACE("ignore basic distinct by hint");
} else if (OB_FAIL(distinct_exprs.assign(in_distinct_exprs))) {
LOG_WARN("failed to assign distinct exprs", K(ret));
} else if (OB_FAIL(ObOptimizerUtil::get_default_directions(distinct_exprs.count(), directions))) {
LOG_WARN("failed to generate default directions", K(ret));
} else if (OB_FAIL(adjust_sort_expr_ordering(distinct_exprs,
directions,
*top,
@ -1660,15 +1696,12 @@ int ObSelectLogPlan::create_merge_distinct_plan(ObLogicalOperator *&top,
LOG_WARN("failed to compute stmt interesting order", K(ret));
} else if (need_sort && can_ignore_merge_plan && OrderingFlag::NOT_MATCH == interesting_order_info) {
// if no further order needed, not generate merge style distinct
is_plan_valid = false;
} else if (top->is_distributed() &&
OB_FAIL(top->check_sharding_compatible_with_reduce_expr(reduce_exprs,
is_partition_wise))) {
top = NULL;
} else if (top->is_distributed() && distinct_helper.allow_partition_wise(top->is_parallel_more_than_part_cnt())
&& OB_FAIL(top->check_sharding_compatible_with_reduce_expr(reduce_exprs,
is_partition_wise))) {
LOG_WARN("failed to check sharding compatible with reduce exprs", K(ret));
} else if (!top->is_distributed() ||
(is_partition_wise &&
!(top->is_parallel_more_than_part_cnt() &&
get_optimizer_context().get_query_ctx()->optimizer_features_enable_version_ > COMPAT_VERSION_4_3_2))) {
} else if (!top->is_distributed() || is_partition_wise) {
OPT_TRACE("is basic distinct:", !top->is_distributed());
OPT_TRACE("is partition wise distinct", is_partition_wise);
if (OB_FAIL(try_allocate_sort_as_top(top, sort_keys, need_sort, prefix_pos))) {

View File

@ -83,7 +83,6 @@ private:
int get_valid_aggr_algo(const ObIArray<ObRawExpr*> &group_by_exprs,
const GroupingOpHelper &groupby_helper,
const bool ignore_hint,
bool &use_hash_valid,
bool &use_merge_valid,
bool &part_sort_valid,
@ -96,9 +95,7 @@ private:
const ObIArray<ObOrderDirection> &rollup_directions,
const ObIArray<ObRawExpr*> &having_exprs,
const ObIArray<ObAggFunRawExpr*> &aggr_items,
const bool is_from_povit,
GroupingOpHelper &groupby_helper,
const bool ignore_hint,
ObIArray<CandidatePlan> &groupby_plans);
int candi_allocate_three_stage_group_by(const ObIArray<ObRawExpr*> &reduce_exprs,
@ -108,7 +105,6 @@ private:
const ObIArray<ObOrderDirection> &rollup_directions,
const ObIArray<ObAggFunRawExpr*> &aggr_items,
const ObIArray<ObRawExpr*> &having_exprs,
const bool is_from_povit,
GroupingOpHelper &groupby_helper,
ObIArray<CandidatePlan> &groupby_plans);
@ -117,7 +113,6 @@ private:
const ObIArray<ObRawExpr*> &rollup_exprs,
const ObIArray<ObAggFunRawExpr*> &aggr_items,
const ObIArray<ObRawExpr*> &having_exprs,
const bool is_from_povit,
GroupingOpHelper &groupby_helper,
ObLogicalOperator *&top);
@ -159,7 +154,6 @@ private:
const ObIArray<ObOrderDirection> &rollup_directions,
const ObIArray<ObAggFunRawExpr*> &aggr_items,
const ObIArray<ObRawExpr*> &having_exprs,
const bool is_from_povit,
GroupingOpHelper &groupby_helper,
CandidatePlan &candidate_plan,
ObIArray<CandidatePlan> &candidate_plans,
@ -186,17 +180,20 @@ private:
common::ObIArray <ObRawExpr *> &reduce_exprs,
common::ObIArray <ObRawExpr *> &distinct_exprs);
int inner_candi_allocate_distinct(const GroupingOpHelper &distinct_helper,
const ObIArray<ObRawExpr*> &reduce_exprs,
const ObIArray<ObRawExpr*> &distinct_exprs,
ObIArray<CandidatePlan> &distinct_plans);
int create_hash_distinct_plan(ObLogicalOperator *&top,
GroupingOpHelper &distinct_helper,
ObIArray<ObRawExpr*> &reduce_exprs,
ObIArray<ObRawExpr*> &distinct_exprs);
const GroupingOpHelper &distinct_helper,
const ObIArray<ObRawExpr*> &reduce_exprs,
const ObIArray<ObRawExpr*> &distinct_exprs);
int create_merge_distinct_plan(ObLogicalOperator *&top,
GroupingOpHelper &distinct_helper,
ObIArray<ObRawExpr*> &reduce_exprs,
ObIArray<ObRawExpr*> &distinct_exprs,
ObIArray<ObOrderDirection> &directions,
bool &is_plan_valid,
const GroupingOpHelper &distinct_helper,
const ObIArray<ObRawExpr*> &reduce_exprs,
const ObIArray<ObRawExpr*> &distinct_exprs,
bool can_ignore_merge_plan = false);
int allocate_distinct_as_top(ObLogicalOperator *&top,
@ -924,7 +921,6 @@ int generate_window_functions_plan(WinFuncOpHelper &win_func_helper,
const ObIArray<ObOrderDirection> &rollup_directions,
const ObIArray<ObAggFunRawExpr*> &aggr_items,
const ObIArray<ObRawExpr*> &having_exprs,
const bool is_from_povit,
GroupingOpHelper &groupby_helper,
ObLogicalOperator *&top,
bool use_part_sort,

View File

@ -1086,6 +1086,7 @@ Timestamp{whitespace}?\"[^\"]*\" {
<hint>BC2HOST { return BC2HOST; }
<hint>RANGE { return RANGE; }
<hint>LIST { return LIST; }
<hint>BASIC { return BASIC; }
<hint>[-] { return NEG_SIGN; }
<hint>MERGE { return MERGE_HINT; }
<hint>NO_MERGE { return NO_MERGE_HINT; }
@ -1171,6 +1172,8 @@ Timestamp{whitespace}?\"[^\"]*\" {
<hint>PUSHDOWN { return PUSHDOWN; }
<hint>DECORRELATE { return DECORRELATE; }
<hint>NO_DECORRELATE { return NO_DECORRELATE; }
<hint>PQ_GBY { return PQ_GBY; }
<hint>PQ_DISTINCT { return PQ_DISTINCT; }
<hint>{identifier} {
if (!(IS_FAST_PARAMETERIZE)) {
check_value(yylval);

View File

@ -190,7 +190,7 @@ USE_HASH_AGGREGATION NO_USE_HASH_AGGREGATION
PARTITION_SORT NO_PARTITION_SORT WF_TOPN
USE_LATE_MATERIALIZATION NO_USE_LATE_MATERIALIZATION
PX_JOIN_FILTER NO_PX_JOIN_FILTER PX_PART_JOIN_FILTER NO_PX_PART_JOIN_FILTER
PQ_MAP PQ_DISTRIBUTE PQ_DISTRIBUTE_WINDOW PQ_SET PQ_SUBQUERY RANDOM_LOCAL BROADCAST BC2HOST LIST
PQ_MAP PQ_DISTRIBUTE PQ_DISTRIBUTE_WINDOW PQ_SET PQ_SUBQUERY PQ_GBY PQ_DISTINCT RANDOM_LOCAL BROADCAST BC2HOST LIST
GBY_PUSHDOWN NO_GBY_PUSHDOWN
USE_HASH_DISTINCT NO_USE_HASH_DISTINCT
DISTINCT_PUSHDOWN NO_DISTINCT_PUSHDOWN
@ -11285,6 +11285,14 @@ INDEX_HINT '(' qb_name_option relation_factor_in_hint NAME_OB opt_index_prefix '
{
malloc_non_terminal_node($$, result->malloc_pool_, T_NO_USE_COLUMN_STORE_HINT, 2, $3, $4);
}
| PQ_GBY '(' qb_name_option distribute_method ')'
{
malloc_non_terminal_node($$, result->malloc_pool_, T_PQ_GBY_HINT, 2, $3, $4);
}
| PQ_DISTINCT '(' qb_name_option distribute_method ')'
{
malloc_non_terminal_node($$, result->malloc_pool_, T_PQ_DISTINCT_HINT, 2, $3, $4);
}
;
opt_index_prefix:
@ -11531,6 +11539,10 @@ ALL
{
malloc_terminal_node($$, result->malloc_pool_, T_DISTRIBUTE_LIST);
}
| BASIC
{
malloc_terminal_node($$, result->malloc_pool_, T_DISTRIBUTE_BASIC);
}
;
limit_expr:

View File

@ -14617,6 +14617,13 @@ int ObDMLResolver::resolve_optimize_hint(const ParseNode &hint_node,
}
break;
}
case T_PQ_GBY_HINT:
case T_PQ_DISTINCT_HINT: {
if (OB_FAIL(resolve_normal_pq_hint(hint_node, opt_hint))) {
LOG_WARN("failed to resolve normal pq hint.", K(ret));
}
break;
}
case T_USE_LATE_MATERIALIZATION:
case T_NO_USE_LATE_MATERIALIZATION:
case T_GBY_PUSHDOWN:
@ -15098,6 +15105,34 @@ int ObDMLResolver::resolve_pq_subquery_hint(const ParseNode &hint_node,
return ret;
}
int ObDMLResolver::resolve_normal_pq_hint(const ParseNode &hint_node,
ObOptHint *&opt_hint)
{
int ret = OB_SUCCESS;
opt_hint = NULL;
const ParseNode *dist_method_node = NULL;
ObPQHint *pq_hint = NULL;
ObString qb_name;
if (OB_UNLIKELY(T_PQ_GBY_HINT != hint_node.type_ && T_PQ_DISTINCT_HINT != hint_node.type_)
|| OB_UNLIKELY(2 != hint_node.num_child_)
|| OB_ISNULL(dist_method_node = hint_node.children_[1])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected pq_gby/pq_distinct hint node", K(ret), K(hint_node.num_child_),
K(get_type_name(hint_node.type_)));
} else if (NULL == ObPQHint::get_dist_method_str(dist_method_node->type_)) {
LOG_TRACE("invalid normal pq hint dist_method_node", K(get_type_name(dist_method_node->type_)));
} else if (OB_FAIL(ObQueryHint::create_hint(allocator_, hint_node.type_, pq_hint))) {
LOG_WARN("failed to create hint", K(ret));
} else if (OB_FAIL(resolve_qb_name_node(hint_node.children_[0], qb_name))) {
LOG_WARN("failed to resolve query block name", K(ret));
} else {
pq_hint->set_qb_name(qb_name);
pq_hint->set_dist_method(dist_method_node->type_);
opt_hint = pq_hint;
}
return ret;
}
int ObDMLResolver::resolve_join_filter_hint(const ParseNode &hint_node,
ObOptHint *&opt_hint)
{

View File

@ -946,6 +946,7 @@ private:
int resolve_pq_distribute_hint(const ParseNode &hint_node, ObOptHint *&opt_hint);
int resolve_pq_set_hint(const ParseNode &hint_node, ObOptHint *&opt_hint);
int resolve_pq_subquery_hint(const ParseNode &hint_node, ObOptHint *&opt_hint);
int resolve_normal_pq_hint(const ParseNode &hint_node, ObOptHint *&opt_hint);
int resolve_join_filter_hint(const ParseNode &join_node, ObOptHint *&opt_hint);
int resolve_aggregation_hint(const ParseNode &hint_node, ObOptHint *&hint);
int resolve_normal_transform_hint(const ParseNode &hint_node, ObTransHint *&hint);

View File

@ -1160,6 +1160,8 @@ const char* ObHint::get_hint_name(ObItemType type, bool is_enable_hint /* defaul
case T_USE_DISTRIBUTED_DML: return is_enable_hint ? "USE_DISTRIBUTED_DML" : "NO_USE_DISTRIBUTED_DML";
case T_TABLE_DYNAMIC_SAMPLING: return "DYNAMIC_SAMPLING";
case T_PQ_SUBQUERY: return "PQ_SUBQUERY";
case T_PQ_GBY_HINT: return "PQ_GBY";
case T_PQ_DISTINCT_HINT: return "PQ_DISTINCT";
default: return NULL;
}
}
@ -2527,6 +2529,43 @@ int ObPQSubqueryHint::print_hint_desc(PlanText &plan_text) const
return ret;
}
int ObPQHint::assign(const ObPQHint &other)
{
int ret = OB_SUCCESS;
dist_method_ = other.dist_method_;
if (OB_FAIL(ObOptHint::assign(other))) {
LOG_WARN("fail to assign hint", K(ret));
}
return ret;
}
int ObPQHint::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_;
const char *str = NULL;
if (OB_ISNULL(str = ObPQHint::get_dist_method_str(dist_method_))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret), K(dist_method_));
} else if (OB_FAIL(BUF_PRINTF(" %s", str))) {
LOG_WARN("failed to print dist method", K(ret));
}
return ret;
}
const char *ObPQHint::get_dist_method_str(ObItemType dist_method)
{
switch (dist_method) {
case T_DISTRIBUTE_BASIC: return "BASIC";
case T_DISTRIBUTE_NONE: return "NONE";
case T_DISTRIBUTE_HASH: return "HASH";
default: return NULL;
}
return NULL;
};
int ObJoinOrderHint::print_hint_desc(PlanText &plan_text) const
{
int ret = OB_SUCCESS;

View File

@ -525,7 +525,8 @@ public:
HINT_TABLE_PARALLEL,
HINT_PQ_SET,
HINT_JOIN_FILTER,
HINT_TABLE_DYNAMIC_SAMPLING
HINT_TABLE_DYNAMIC_SAMPLING,
HINT_PQ
};
static const int64_t MAX_EXPR_STR_LENGTH_IN_HINT = 1024;
@ -992,7 +993,7 @@ public:
const ObTableInHint &get_table() const { return table_; }
int64_t get_parallel() const { return parallel_; }
void set_parallel(int64_t parallel) { parallel_ = parallel; }
INHERIT_TO_STRING_KV("ObHint", ObHint, K_(table), K_(table), K_(parallel));
INHERIT_TO_STRING_KV("ObHint", ObHint, K_(table), K_(parallel));
private:
ObTableInHint table_;
@ -1114,6 +1115,31 @@ private:
QbNameList sub_qb_names_;
};
// normal pq hint for single child op: group by/distinct
class ObPQHint : public ObOptHint
{
public:
ObPQHint(ObItemType hint_type)
: ObOptHint(hint_type),
dist_method_(T_INVALID)
{
set_hint_class(HINT_PQ);
}
int assign(const ObPQHint &other);
virtual ~ObPQHint() {}
virtual int print_hint_desc(PlanText &plan_text) const override;
static const char* get_dist_method_str(ObItemType dist_method);
void set_dist_method(ObItemType dist_method) { dist_method_ = dist_method; }
inline bool is_dist_method_match(ObItemType dist_method) const { return dist_method_ == dist_method; }
inline bool is_force_basic() const { return T_DISTRIBUTE_BASIC == dist_method_; }
inline bool is_force_partition_wise() const { return T_DISTRIBUTE_NONE == dist_method_; }
inline bool is_force_dist_hash() const { return T_DISTRIBUTE_HASH == dist_method_; }
INHERIT_TO_STRING_KV("ObHint", ObHint, K_(dist_method));
private:
ObItemType dist_method_;
};
class ObJoinOrderHint : public ObOptHint {
public:
ObJoinOrderHint(ObItemType hint_type = T_LEADING)

View File

@ -1405,7 +1405,7 @@ void ObLogPlanHint::reset()
table_hints_.reuse();
join_hints_.reuse();
normal_hints_.reuse();
enable_index_prefix_ = false;
optimizer_features_enable_version_ = LASTED_COMPAT_VERSION;
}
#ifndef OB_BUILD_SPM
@ -1425,7 +1425,7 @@ int ObLogPlanHint::init_log_plan_hint(ObSqlSchemaGuard &schema_guard,
#ifdef OB_BUILD_SPM
is_spm_evolution_ = is_spm_evolution;
#endif
enable_index_prefix_ = (stmt.get_query_ctx()->optimizer_features_enable_version_ >= COMPAT_VERSION_4_2_3);
optimizer_features_enable_version_ = stmt.get_query_ctx()->optimizer_features_enable_version_;
const ObStmtHint &stmt_hint = stmt.get_stmt_hint();
if (OB_FAIL(join_order_.init_leading_info(stmt, query_hint, stmt_hint.get_normal_hint(T_LEADING)))) {
LOG_WARN("failed to get leading hint info", K(ret));
@ -1721,14 +1721,23 @@ bool ObLogPlanHint::has_disable_hint(ObItemType hint_type) const
int ObLogPlanHint::get_aggregation_info(bool &force_use_hash,
bool &force_use_merge,
bool &force_part_sort,
bool &force_normal_sort) const
bool &force_normal_sort,
bool &force_basic,
bool &force_partition_wise,
bool &force_dist_hash) const
{
int ret = OB_SUCCESS;
force_use_hash = false;
force_use_merge = false;
force_part_sort = false;
force_normal_sort = false;
force_basic = false;
force_partition_wise = false;
force_dist_hash = false;
const ObAggHint *agg_hint = static_cast<const ObAggHint*>(get_normal_hint(T_USE_HASH_AGGREGATE));
const ObPQHint *pq_hint = static_cast<const ObPQHint*>(get_normal_hint(T_PQ_GBY_HINT));
const bool enable_pq_hint = COMPAT_VERSION_4_3_3 <= optimizer_features_enable_version_
|| COMPAT_VERSION_4_2_4 < optimizer_features_enable_version_;
if (NULL != agg_hint) {
force_use_hash = agg_hint->is_enable_hint();
force_use_merge = agg_hint->is_disable_hint();
@ -1741,6 +1750,51 @@ int ObLogPlanHint::get_aggregation_info(bool &force_use_hash,
force_use_merge = true;
force_normal_sort = true;
}
if (OB_FAIL(ret) || !enable_pq_hint) {
} else if (NULL != pq_hint) {
force_basic = pq_hint->is_force_basic();
force_partition_wise = pq_hint->is_force_partition_wise();
force_dist_hash = pq_hint->is_force_dist_hash();
} else if (is_outline_data_) {
force_basic = true;
force_partition_wise = false;
force_dist_hash = false;
}
return ret;
}
int ObLogPlanHint::get_distinct_info(bool &force_use_hash,
bool &force_use_merge,
bool &force_basic,
bool &force_partition_wise,
bool &force_dist_hash) const
{
int ret = OB_SUCCESS;
force_use_hash = false;
force_use_merge = false;
force_basic = false;
force_partition_wise = false;
force_dist_hash = false;
const ObHint *method_hint = static_cast<const ObAggHint*>(get_normal_hint(T_USE_HASH_DISTINCT));
const ObPQHint *pq_hint = static_cast<const ObPQHint*>(get_normal_hint(T_PQ_DISTINCT_HINT));
const bool enable_pq_hint = COMPAT_VERSION_4_3_3 <= optimizer_features_enable_version_
|| COMPAT_VERSION_4_2_4 < optimizer_features_enable_version_;
if (NULL != method_hint) {
force_use_hash = method_hint->is_enable_hint();
force_use_merge = method_hint->is_disable_hint();
} else if (is_outline_data_) {
force_use_merge = true;
}
if (OB_FAIL(ret) || !enable_pq_hint) {
} else if (NULL != pq_hint) {
force_basic = pq_hint->is_force_basic();
force_partition_wise = pq_hint->is_force_partition_wise();
force_dist_hash = pq_hint->is_force_dist_hash();
} else if (is_outline_data_) {
force_basic = true;
force_partition_wise = false;
force_dist_hash = false;
}
return ret;
}
@ -1941,7 +1995,8 @@ int ObLogPlanHint::get_index_prefix(const uint64_t table_id,
{
int ret = OB_SUCCESS;
const LogTableHint *log_table_hint = NULL;
if (!enable_index_prefix_ || OB_ISNULL(log_table_hint = get_index_hint(table_id))) {
if (optimizer_features_enable_version_ < COMPAT_VERSION_4_2_3
|| OB_ISNULL(log_table_hint = get_index_hint(table_id))) {
//do nothing
} else if (!log_table_hint->is_use_index_hint()) {
//do nothing

View File

@ -470,7 +470,15 @@ struct ObLogPlanHint
int get_aggregation_info(bool &force_use_hash,
bool &force_use_merge,
bool &force_part_sort,
bool &force_normal_sort) const;
bool &force_normal_sort,
bool &force_basic,
bool &force_partition_wise,
bool &force_dist_hash) const;
int get_distinct_info(bool &force_use_hash,
bool &force_use_merge,
bool &force_basic,
bool &force_partition_wise,
bool &force_dist_hash) const;
int get_valid_pq_subquery_hint(const ObIArray<ObString> &sub_qb_names,
const ObPQSubqueryHint *&explicit_hint,
const ObPQSubqueryHint *&implicit_hint) const;
@ -482,12 +490,8 @@ struct ObLogPlanHint
bool use_late_material() const { return has_enable_hint(T_USE_LATE_MATERIALIZATION); }
bool no_use_late_material() const { return has_disable_hint(T_USE_LATE_MATERIALIZATION); }
bool use_hash_aggregate() const { return has_enable_hint(T_USE_HASH_AGGREGATE); }
bool use_merge_aggregate() const { return has_disable_hint(T_USE_HASH_AGGREGATE); }
bool pushdown_group_by() const { return has_enable_hint(T_GBY_PUSHDOWN); }
bool no_pushdown_group_by() const { return has_disable_hint(T_GBY_PUSHDOWN); }
bool use_hash_distinct() const { return has_enable_hint(T_USE_HASH_DISTINCT); }
bool use_merge_distinct() const { return has_disable_hint(T_USE_HASH_DISTINCT); }
bool pushdown_distinct() const { return has_enable_hint(T_DISTINCT_PUSHDOWN); }
bool no_pushdown_distinct() const { return has_disable_hint(T_DISTINCT_PUSHDOWN); }
bool use_distributed_dml() const { return has_enable_hint(T_USE_DISTRIBUTED_DML); }
@ -497,7 +501,7 @@ struct ObLogPlanHint
TO_STRING_KV(K_(is_outline_data), K_(join_order),
K_(table_hints), K_(join_hints),
K_(normal_hints), K_(enable_index_prefix));
K_(normal_hints), K_(optimizer_features_enable_version));
bool is_outline_data_;
#ifdef OB_BUILD_SPM
@ -507,7 +511,7 @@ struct ObLogPlanHint
common::ObSEArray<LogTableHint, 4, common::ModulePageAllocator, true> table_hints_;
common::ObSEArray<LogJoinHint, 8, common::ModulePageAllocator, true> join_hints_;
common::ObSEArray<const ObHint*, 8, common::ModulePageAllocator, true> normal_hints_;
bool enable_index_prefix_;
uint64_t optimizer_features_enable_version_;
};
}