From 38896ca913b0781353ad5c720a7eb5e82a46d92e Mon Sep 17 00:00:00 2001 From: chimyue Date: Wed, 21 Aug 2024 12:26:57 +0000 Subject: [PATCH] add pq_gby/pq_distinct hint, fix some outline bug --- src/objit/include/objit/common/ob_item_type.h | 5 + src/sql/optimizer/ob_join_order.cpp | 20 +- src/sql/optimizer/ob_log_distinct.cpp | 26 +- src/sql/optimizer/ob_log_group_by.cpp | 12 + src/sql/optimizer/ob_log_group_by.h | 15 +- src/sql/optimizer/ob_log_plan.cpp | 132 +++++--- src/sql/optimizer/ob_log_plan.h | 31 +- src/sql/optimizer/ob_select_log_plan.cpp | 283 ++++++++++-------- src/sql/optimizer/ob_select_log_plan.h | 26 +- src/sql/parser/sql_parser_mysql_mode.l | 3 + src/sql/parser/sql_parser_mysql_mode.y | 14 +- src/sql/resolver/dml/ob_dml_resolver.cpp | 35 +++ src/sql/resolver/dml/ob_dml_resolver.h | 1 + src/sql/resolver/dml/ob_hint.cpp | 39 +++ src/sql/resolver/dml/ob_hint.h | 30 +- src/sql/resolver/dml/ob_sql_hint.cpp | 63 +++- src/sql/resolver/dml/ob_sql_hint.h | 18 +- 17 files changed, 539 insertions(+), 214 deletions(-) diff --git a/src/objit/include/objit/common/ob_item_type.h b/src/objit/include/objit/common/ob_item_type.h index fe8c733c0..46ed636d1 100755 --- a/src/objit/include/objit/common/ob_item_type.h +++ b/src/objit/include/objit/common/ob_item_type.h @@ -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; diff --git a/src/sql/optimizer/ob_join_order.cpp b/src/sql/optimizer/ob_join_order.cpp index f06e5ab72..92af4115b 100644 --- a/src/sql/optimizer/ob_join_order.cpp +++ b/src/sql/optimizer/ob_join_order.cpp @@ -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"); } diff --git a/src/sql/optimizer/ob_log_distinct.cpp b/src/sql/optimizer/ob_log_distinct.cpp index fbb2c9310..2e147f75e 100644 --- a/src/sql/optimizer/ob_log_distinct.cpp +++ b/src/sql/optimizer/ob_log_distinct.cpp @@ -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(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)); } } } diff --git a/src/sql/optimizer/ob_log_group_by.cpp b/src/sql/optimizer/ob_log_group_by.cpp index 83bece9f0..49df0d1b5 100644 --- a/src/sql/optimizer/ob_log_group_by.cpp +++ b/src/sql/optimizer/ob_log_group_by.cpp @@ -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(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(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; } diff --git a/src/sql/optimizer/ob_log_group_by.h b/src/sql/optimizer/ob_log_group_by.h index 61462d2d1..0ac2f8eb4 100644 --- a/src/sql/optimizer/ob_log_group_by.h +++ b/src/sql/optimizer/ob_log_group_by.h @@ -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 diff --git a/src/sql/optimizer/ob_log_plan.cpp b/src/sql/optimizer/ob_log_plan.cpp index fe9fa6972..9ae0ef781 100644 --- a/src/sql/optimizer/ob_log_plan.cpp +++ b/src/sql/optimizer/ob_log_plan.cpp @@ -5201,7 +5201,7 @@ int ObLogPlan::create_three_stage_group_plan(const ObIArray &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 &a const bool is_from_povit) { int ret = OB_SUCCESS; - ObSEArray best_plans; + ObSEArray groupby_plans; ObSEArray 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 &agg_items, + const ObIArray &having_exprs, + GroupingOpHelper &groupby_helper, + ObIArray &groupby_plans) + +{ + int ret = OB_SUCCESS; + ObSEArray 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 &a int ObLogPlan::create_scala_group_plan(const ObIArray &aggr_items, const ObIArray &having_exprs, - const bool is_from_povit, GroupingOpHelper &groupby_helper, ObLogicalOperator *&top) { @@ -5411,23 +5444,24 @@ int ObLogPlan::create_scala_group_plan(const ObIArray &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(top)->set_group_by_outline_info(false, false); + static_cast(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 &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 &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(top)->set_group_by_outline_info(false, groupby_helper.can_basic_pushdown_ || is_partition_wise); + static_cast(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 &group_exprs, ObSEArray 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 &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 &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)); diff --git a/src/sql/optimizer/ob_log_plan.h b/src/sql/optimizer/ob_log_plan.h index a645e52f1..ba8e46f3d 100644 --- a/src/sql/optimizer/ob_log_plan.h +++ b/src/sql/optimizer/ob_log_plan.h @@ -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 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 &having_exprs, const bool is_from_povit); + int inner_candi_allocate_scala_group_by(const ObIArray &agg_items, + const ObIArray &having_exprs, + GroupingOpHelper &groupby_helper, + ObIArray &groupby_plans); + int prepare_three_stage_info(const ObIArray &group_by_exprs, const ObIArray &rollup_exprs, GroupingOpHelper &helper); @@ -712,7 +742,6 @@ public: int create_scala_group_plan(const ObIArray &agg_items, const ObIArray &having_exprs, - const bool is_from_povit, GroupingOpHelper &groupby_helper, ObLogicalOperator *&top); diff --git a/src/sql/optimizer/ob_select_log_plan.cpp b/src/sql/optimizer/ob_select_log_plan.cpp index a8c5cc54a..e65c3aacb 100644 --- a/src/sql/optimizer/ob_select_log_plan.cpp +++ b/src/sql/optimizer/ob_select_log_plan.cpp @@ -265,10 +265,28 @@ int ObSelectLogPlan::candi_allocate_normal_group_by(const ObIArray & 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 & 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 & 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 & 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 &rollup_directions, const ObIArray &aggr_items, const ObIArray &having_exprs, - const bool is_from_povit, GroupingOpHelper &groupby_helper, ObIArray &groupby_plans) { @@ -344,14 +358,13 @@ int ObSelectLogPlan::candi_allocate_three_stage_group_by(const ObIArrayis_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 &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 &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 & const ObIArray &rollup_directions, const ObIArray &having_exprs, const ObIArray &aggr_items, - const bool is_from_povit, GroupingOpHelper &groupby_helper, - const bool ignore_hint, ObIArray &groupby_plans) { int ret = OB_SUCCESS; @@ -481,7 +490,7 @@ int ObSelectLogPlan::candi_allocate_normal_group_by(const ObIArray & 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 & 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 & 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 &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 &reduce_e const ObIArray &rollup_exprs, const ObIArray &aggr_items, const ObIArray &having_exprs, - const bool is_from_povit, GroupingOpHelper &groupby_helper, ObLogicalOperator *&top) { @@ -736,26 +742,28 @@ int ObSelectLogPlan::create_hash_group_plan(const ObIArray &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(top)->set_group_by_outline_info(true, false); + static_cast(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 &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 &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(top)->set_group_by_outline_info(true, groupby_helper.can_basic_pushdown_); + static_cast(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 &reduce_ const ObIArray &rollup_directions, const ObIArray &aggr_items, const ObIArray &having_exprs, - const bool is_from_povit, GroupingOpHelper &groupby_helper, CandidatePlan &candidate_plan, ObIArray &candidate_plans, @@ -973,7 +980,6 @@ int ObSelectLogPlan::create_merge_group_plan(const ObIArray &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 &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 &r const ObIArray &rollup_directions, const ObIArray &aggr_items, const ObIArray &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 &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 &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(top)->set_group_by_outline_info(false, false, use_part_sort); + static_cast(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 &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 &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(top)->set_group_by_outline_info(false, + static_cast(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 distinct_plans; - ObSEArray distinct_directions; ObSEArray 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 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 &reduce_exprs, + const ObIArray &distinct_exprs, + ObIArray &distinct_plans) +{ + int ret = OB_SUCCESS; + CandidatePlan candidate_plan; + // create hash distinct + if (OB_SUCC(ret) && !distinct_helper.force_use_merge_) { + ObSEArray 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 &reduce_exprs, ObIArray &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 &reduce_exprs, - ObIArray &distinct_exprs) + const GroupingOpHelper &distinct_helper, + const ObIArray &reduce_exprs, + const ObIArray &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 &reduce_exprs, - ObIArray &distinct_exprs, - ObIArray &directions, - bool &is_plan_valid, + const GroupingOpHelper &distinct_helper, + const ObIArray &reduce_exprs, + const ObIArray &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 sort_keys; int64_t interesting_order_info = OrderingFlag::NOT_MATCH; - is_plan_valid = true; + ObSEArray distinct_exprs; + ObSEArray 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))) { diff --git a/src/sql/optimizer/ob_select_log_plan.h b/src/sql/optimizer/ob_select_log_plan.h index 0ae361ee9..cc292c6a8 100644 --- a/src/sql/optimizer/ob_select_log_plan.h +++ b/src/sql/optimizer/ob_select_log_plan.h @@ -83,7 +83,6 @@ private: int get_valid_aggr_algo(const ObIArray &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 &rollup_directions, const ObIArray &having_exprs, const ObIArray &aggr_items, - const bool is_from_povit, GroupingOpHelper &groupby_helper, - const bool ignore_hint, ObIArray &groupby_plans); int candi_allocate_three_stage_group_by(const ObIArray &reduce_exprs, @@ -108,7 +105,6 @@ private: const ObIArray &rollup_directions, const ObIArray &aggr_items, const ObIArray &having_exprs, - const bool is_from_povit, GroupingOpHelper &groupby_helper, ObIArray &groupby_plans); @@ -117,7 +113,6 @@ private: const ObIArray &rollup_exprs, const ObIArray &aggr_items, const ObIArray &having_exprs, - const bool is_from_povit, GroupingOpHelper &groupby_helper, ObLogicalOperator *&top); @@ -159,7 +154,6 @@ private: const ObIArray &rollup_directions, const ObIArray &aggr_items, const ObIArray &having_exprs, - const bool is_from_povit, GroupingOpHelper &groupby_helper, CandidatePlan &candidate_plan, ObIArray &candidate_plans, @@ -186,17 +180,20 @@ private: common::ObIArray &reduce_exprs, common::ObIArray &distinct_exprs); + int inner_candi_allocate_distinct(const GroupingOpHelper &distinct_helper, + const ObIArray &reduce_exprs, + const ObIArray &distinct_exprs, + ObIArray &distinct_plans); + int create_hash_distinct_plan(ObLogicalOperator *&top, - GroupingOpHelper &distinct_helper, - ObIArray &reduce_exprs, - ObIArray &distinct_exprs); + const GroupingOpHelper &distinct_helper, + const ObIArray &reduce_exprs, + const ObIArray &distinct_exprs); int create_merge_distinct_plan(ObLogicalOperator *&top, - GroupingOpHelper &distinct_helper, - ObIArray &reduce_exprs, - ObIArray &distinct_exprs, - ObIArray &directions, - bool &is_plan_valid, + const GroupingOpHelper &distinct_helper, + const ObIArray &reduce_exprs, + const ObIArray &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 &rollup_directions, const ObIArray &aggr_items, const ObIArray &having_exprs, - const bool is_from_povit, GroupingOpHelper &groupby_helper, ObLogicalOperator *&top, bool use_part_sort, diff --git a/src/sql/parser/sql_parser_mysql_mode.l b/src/sql/parser/sql_parser_mysql_mode.l index 47f2a1465..964e9715e 100644 --- a/src/sql/parser/sql_parser_mysql_mode.l +++ b/src/sql/parser/sql_parser_mysql_mode.l @@ -1086,6 +1086,7 @@ Timestamp{whitespace}?\"[^\"]*\" { BC2HOST { return BC2HOST; } RANGE { return RANGE; } LIST { return LIST; } +BASIC { return BASIC; } [-] { return NEG_SIGN; } MERGE { return MERGE_HINT; } NO_MERGE { return NO_MERGE_HINT; } @@ -1171,6 +1172,8 @@ Timestamp{whitespace}?\"[^\"]*\" { PUSHDOWN { return PUSHDOWN; } DECORRELATE { return DECORRELATE; } NO_DECORRELATE { return NO_DECORRELATE; } +PQ_GBY { return PQ_GBY; } +PQ_DISTINCT { return PQ_DISTINCT; } {identifier} { if (!(IS_FAST_PARAMETERIZE)) { check_value(yylval); diff --git a/src/sql/parser/sql_parser_mysql_mode.y b/src/sql/parser/sql_parser_mysql_mode.y index 695d2bc71..1b6a44557 100644 --- a/src/sql/parser/sql_parser_mysql_mode.y +++ b/src/sql/parser/sql_parser_mysql_mode.y @@ -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: diff --git a/src/sql/resolver/dml/ob_dml_resolver.cpp b/src/sql/resolver/dml/ob_dml_resolver.cpp index 4ba31d2c3..01aaafd98 100755 --- a/src/sql/resolver/dml/ob_dml_resolver.cpp +++ b/src/sql/resolver/dml/ob_dml_resolver.cpp @@ -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) { diff --git a/src/sql/resolver/dml/ob_dml_resolver.h b/src/sql/resolver/dml/ob_dml_resolver.h index c29907b91..6e8f06689 100644 --- a/src/sql/resolver/dml/ob_dml_resolver.h +++ b/src/sql/resolver/dml/ob_dml_resolver.h @@ -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); diff --git a/src/sql/resolver/dml/ob_hint.cpp b/src/sql/resolver/dml/ob_hint.cpp index b838c6051..1275f485b 100644 --- a/src/sql/resolver/dml/ob_hint.cpp +++ b/src/sql/resolver/dml/ob_hint.cpp @@ -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; diff --git a/src/sql/resolver/dml/ob_hint.h b/src/sql/resolver/dml/ob_hint.h index 40afd02ca..d914dbe38 100644 --- a/src/sql/resolver/dml/ob_hint.h +++ b/src/sql/resolver/dml/ob_hint.h @@ -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) diff --git a/src/sql/resolver/dml/ob_sql_hint.cpp b/src/sql/resolver/dml/ob_sql_hint.cpp index 0d6264a0f..64c6e1a9f 100644 --- a/src/sql/resolver/dml/ob_sql_hint.cpp +++ b/src/sql/resolver/dml/ob_sql_hint.cpp @@ -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(get_normal_hint(T_USE_HASH_AGGREGATE)); + const ObPQHint *pq_hint = static_cast(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(get_normal_hint(T_USE_HASH_DISTINCT)); + const ObPQHint *pq_hint = static_cast(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 diff --git a/src/sql/resolver/dml/ob_sql_hint.h b/src/sql/resolver/dml/ob_sql_hint.h index 9b41aabdf..5ac9ad1dc 100644 --- a/src/sql/resolver/dml/ob_sql_hint.h +++ b/src/sql/resolver/dml/ob_sql_hint.h @@ -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 &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 table_hints_; common::ObSEArray join_hints_; common::ObSEArray normal_hints_; - bool enable_index_prefix_; + uint64_t optimizer_features_enable_version_; }; }