From 781b365061bed10ae28ad0f6ee63b1b0f5b79226 Mon Sep 17 00:00:00 2001 From: jingtaoye35 <1255153887@qq.com> Date: Tue, 9 Apr 2024 12:12:17 +0000 Subject: [PATCH] [CP] fix losting order in select_plan --- src/sql/optimizer/ob_log_exchange.cpp | 10 ++++++ src/sql/optimizer/ob_log_plan.cpp | 3 +- src/sql/optimizer/ob_logical_operator.h | 4 +-- src/sql/optimizer/ob_select_log_plan.cpp | 41 ++++++++++++++++++------ src/sql/optimizer/ob_select_log_plan.h | 2 +- 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/sql/optimizer/ob_log_exchange.cpp b/src/sql/optimizer/ob_log_exchange.cpp index 531fb2a30..536827b3d 100644 --- a/src/sql/optimizer/ob_log_exchange.cpp +++ b/src/sql/optimizer/ob_log_exchange.cpp @@ -344,6 +344,13 @@ int ObLogExchange::print_annotation_keys(char *buf, return ret; } +/* If using merge sort, then set local = False, range = False + * If using task sort and range order is True, then set local = False, range = False + * Otherwise, + * local,range | inherit | inherit | True, False | True, False | + * EXCHANGE IN | LOCAL/REMOTE/ALL | DISTRUBUTE | LOCAL/REMOTE/ALL | DISTRUBUTE | + * EXCHANGE OUT | LOCAL/REMOTE/ALL | LOCAL/REMOTE/ALL | DISTRUBUTE | DISTRUBUTE | +*/ int ObLogExchange::compute_op_ordering() { int ret = OB_SUCCESS; @@ -368,6 +375,9 @@ int ObLogExchange::compute_op_ordering() is_local_order_ = false; is_range_order_ = false; } + } else if (is_task_order_) { + is_local_order_ = false; + is_range_order_ = false; } else if (!get_op_ordering().empty() && child->is_distributed()) { is_local_order_ = true; is_range_order_ = false; diff --git a/src/sql/optimizer/ob_log_plan.cpp b/src/sql/optimizer/ob_log_plan.cpp index 0515adbc4..7ac0843e9 100644 --- a/src/sql/optimizer/ob_log_plan.cpp +++ b/src/sql/optimizer/ob_log_plan.cpp @@ -8429,7 +8429,8 @@ int ObLogPlan::allocate_sort_and_exchange_as_top(ObLogicalOperator *&top, } // allocate push down sort if necessary - if ((exch_info.is_pq_local() || !exch_info.need_exchange()) && !sort_keys.empty() && + if (OB_SUCC(ret) && + (exch_info.is_pq_local() || !exch_info.need_exchange()) && !sort_keys.empty() && (need_sort || is_local_order)) { int64_t real_prefix_pos = need_sort && !is_local_order ? prefix_pos : 0; bool real_local_order = need_sort ? false : is_local_order; diff --git a/src/sql/optimizer/ob_logical_operator.h b/src/sql/optimizer/ob_logical_operator.h index 670f7674b..f55d04a3d 100644 --- a/src/sql/optimizer/ob_logical_operator.h +++ b/src/sql/optimizer/ob_logical_operator.h @@ -1165,9 +1165,9 @@ public: * get cur_op's expected_ordering */ inline void set_is_local_order(bool is_local_order) { is_local_order_ = is_local_order; } - inline bool get_is_local_order() { return is_local_order_; } + inline bool get_is_local_order() const { return is_local_order_; } inline void set_is_range_order(bool is_range_order) { is_range_order_ = is_range_order; } - inline bool get_is_range_order() { return is_range_order_; } + inline bool get_is_range_order() const { return is_range_order_; } inline void set_is_at_most_one_row(bool is_at_most_one_row) { is_at_most_one_row_ = is_at_most_one_row; } inline bool get_is_at_most_one_row() { return is_at_most_one_row_; } diff --git a/src/sql/optimizer/ob_select_log_plan.cpp b/src/sql/optimizer/ob_select_log_plan.cpp index dd110be73..32f11e266 100644 --- a/src/sql/optimizer/ob_select_log_plan.cpp +++ b/src/sql/optimizer/ob_select_log_plan.cpp @@ -4351,6 +4351,7 @@ int ObSelectLogPlan::allocate_plan_top() } else { bool need_limit = true; bool for_update_is_allocated = false; + bool need_alloc_select_item = true; ObSEArray order_items; LOG_TRACE("start to allocate operators for ", "sql", optimizer_context_.get_query_ctx()->get_sql_stmt()); // step. allocate subplan filter if needed, mainly for the subquery in where statement @@ -4446,13 +4447,24 @@ int ObSelectLogPlan::allocate_plan_top() // step. allocate 'order-by' if needed if (OB_SUCC(ret) && select_stmt->has_order_by() && !select_stmt->is_order_siblings() && !get_optimizer_context().is_online_ddl()) { - candidates_.is_final_sort_ = true; - if (OB_FAIL(candi_allocate_order_by(need_limit, order_items))) { - LOG_WARN("failed to allocate order by operator", K(ret)); - } else { - candidates_.is_final_sort_ = false; - LOG_TRACE("succeed to allocate order by operator", + if (!select_stmt->has_limit()) { + if (OB_FAIL(candi_allocate_subplan_filter_for_select_item(order_items))) { + LOG_WARN("failed to allocate subplan filter for subquery in select item", K(ret)); + } else { + need_alloc_select_item = false; + LOG_TRACE("succeed to allocate subplan filter for subquery in select item", + K(candidates_.candidate_plans_.count())); + } + } + if (OB_SUCC(ret)) { + candidates_.is_final_sort_ = true; + if (OB_FAIL(candi_allocate_order_by(need_limit, order_items))) { + LOG_WARN("failed to allocate order by operator", K(ret)); + } else { + candidates_.is_final_sort_ = false; + LOG_TRACE("succeed to allocate order by operator", K(candidates_.candidate_plans_.count())); + } } } @@ -4477,8 +4489,8 @@ int ObSelectLogPlan::allocate_plan_top() } // step. allocate subplan filter if needed, mainly for subquery in select item - if (OB_SUCC(ret)) { - if (OB_FAIL(candi_allocate_subplan_filter_for_select_item())) { + if (OB_SUCC(ret) && need_alloc_select_item) { + if (OB_FAIL(candi_allocate_subplan_filter_for_select_item(order_items))) { LOG_WARN("failed to allocate subplan filter for subquery in select item", K(ret)); } else { LOG_TRACE("succeed to allocate subplan filter for subquery in select item", @@ -4603,7 +4615,7 @@ int ObSelectLogPlan::generate_raw_plan_for_expr_values() return ret; } -int ObSelectLogPlan::candi_allocate_subplan_filter_for_select_item() +int ObSelectLogPlan::candi_allocate_subplan_filter_for_select_item(ObIArray &order_items) { int ret = OB_SUCCESS; const ObSelectStmt *select_stmt = NULL; @@ -4616,7 +4628,16 @@ int ObSelectLogPlan::candi_allocate_subplan_filter_for_select_item() LOG_WARN("failed to get select exprs", K(ret)); } else if (OB_FAIL(candi_allocate_subplan_filter(select_exprs))) { LOG_WARN("failed to candi allocate subplan filter for exprs", K(ret)); - } else { + } else if (!order_items.empty()) { + for (int64_t i = 0; OB_SUCC(ret) && i < candidates_.candidate_plans_.count(); i++) { + // create sort operator if needed + if (OB_FAIL(create_order_by_plan(candidates_.candidate_plans_.at(i).plan_tree_, + order_items, NULL, false))) { + LOG_WARN("failed to create order by plan", K(ret)); + } + } + } + if (OB_SUCC(ret)) { LOG_TRACE("succeed to allocate subplan filter for select item", K(select_stmt->get_stmt_id())); } return ret; diff --git a/src/sql/optimizer/ob_select_log_plan.h b/src/sql/optimizer/ob_select_log_plan.h index 66bbd03f9..486e5027a 100644 --- a/src/sql/optimizer/ob_select_log_plan.h +++ b/src/sql/optimizer/ob_select_log_plan.h @@ -473,7 +473,7 @@ private: * @return */ // int process_subplan(); - int candi_allocate_subplan_filter_for_select_item(); + int candi_allocate_subplan_filter_for_select_item(common::ObIArray &order_items); struct WinFuncOpHelper {