diff --git a/src/sql/rewrite/ob_stmt_comparer.cpp b/src/sql/rewrite/ob_stmt_comparer.cpp index e43ea9339c..2bd61e2b32 100644 --- a/src/sql/rewrite/ob_stmt_comparer.cpp +++ b/src/sql/rewrite/ob_stmt_comparer.cpp @@ -256,28 +256,15 @@ bool ObStmtCompareContext::compare_query(const ObQueryRefRawExpr &first, } else if (OB_FAIL(ObStmtComparer::check_stmt_containment(first_sel, second_sel, stmt_map_info, - relation))) { + relation, + true))) { LOG_WARN("failed to compute stmt relationship", K(ret)); err_code_ = ret; } else if (stmt_map_info.is_select_item_equal_ && QueryRelation::QUERY_EQUAL == relation) { - bool is_same = true; - for (int64_t i = 0; OB_SUCC(ret) && is_same && i < first_sel->get_select_item_size(); ++i) { - ObRawExpr *first_expr = first_sel->get_select_item(i).expr_; - ObRawExpr *second_expr = second_sel->get_select_item(i).expr_; - if (OB_ISNULL(first_expr) || OB_ISNULL(second_expr)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null", K(ret), KP(first_expr), KP(second_expr)); - err_code_ = ret; - } else { - is_same = first_expr->same_as(*second_expr, this); - } - } - if (OB_SUCC(ret) && is_same) { - bret = true; - if (OB_FAIL(append(equal_param_info_, stmt_map_info.equal_param_map_))) { - LOG_WARN("failed to append equal param", K(ret)); - err_code_ = ret; - } + bret = true; + if (OB_FAIL(append(equal_param_info_, stmt_map_info.equal_param_map_))) { + LOG_WARN("failed to append equal param", K(ret)); + err_code_ = ret; } } return bret; @@ -399,7 +386,8 @@ int ObStmtComparer::is_same_from(const ObDMLStmt *first, int ObStmtComparer::check_stmt_containment(const ObDMLStmt *first, const ObDMLStmt *second, ObStmtMapInfo &map_info, - QueryRelation &relation) + QueryRelation &relation, + bool is_strict_select_list) { int ret = OB_SUCCESS; int64_t first_count = 0; @@ -682,7 +670,8 @@ int ObStmtComparer::check_stmt_containment(const ObDMLStmt *first, second_exprs, map_info, map_info.select_item_map_, - match_count))) { + match_count, + is_strict_select_list))) { LOG_WARN("failed to compute output expr map", K(ret)); } else if (match_count == first_exprs.count() && match_count == second_exprs.count()) { map_info.is_select_item_equal_ = true; @@ -751,7 +740,8 @@ int ObStmtComparer::compute_conditions_map(const ObDMLStmt *first, const ObIArray &second_exprs, ObStmtMapInfo &map_info, ObIArray &condition_map, - int64_t &match_count) + int64_t &match_count, + bool is_same_by_order) { int ret = OB_SUCCESS; ObSqlBitSet<> matched_items; @@ -766,23 +756,45 @@ int ObStmtComparer::compute_conditions_map(const ObDMLStmt *first, for (int64_t i = 0; OB_SUCC(ret) && i < first_exprs.count(); ++i) { bool is_match = false; condition_map.at(i) = OB_INVALID_ID; - for (int64_t j = 0; OB_SUCC(ret) && !is_match && j < second_exprs.count(); ++j) { - if (matched_items.has_member(j)) { - // do nothing - } else if (OB_FAIL(is_same_condition(first_exprs.at(i), - second_exprs.at(j), - context, - is_match))) { - LOG_WARN("failed to check is condition equal", K(ret)); - } else if (!is_match) { - // do nothing - } else if (OB_FAIL(append(map_info.equal_param_map_, context.equal_param_info_))) { - LOG_WARN("failed to append exprs", K(ret)); - } else if (OB_FAIL(matched_items.add_member(j))) { - LOG_WARN("failed to add member", K(ret)); - } else { - match_count++; - condition_map.at(i) = j; + if (!is_same_by_order) { + // is same to any one + for (int64_t j = 0; OB_SUCC(ret) && !is_match && j < second_exprs.count(); ++j) { + if (matched_items.has_member(j)) { + // do nothing + } else if (OB_FAIL(is_same_condition(first_exprs.at(i), + second_exprs.at(j), + context, + is_match))) { + LOG_WARN("failed to check is condition equal", K(ret)); + } else if (!is_match) { + // do nothing + } else if (OB_FAIL(append(map_info.equal_param_map_, context.equal_param_info_))) { + LOG_WARN("failed to append exprs", K(ret)); + } else if (OB_FAIL(matched_items.add_member(j))) { + LOG_WARN("failed to add member", K(ret)); + } else { + match_count++; + condition_map.at(i) = j; + } + } + } else { + // is same by order + if (i < second_exprs.count()) { + if (OB_FAIL(is_same_condition(first_exprs.at(i), + second_exprs.at(i), + context, + is_match))) { + LOG_WARN("failed to check is condition equal", K(ret)); + } else if (!is_match) { + // do nothing + } else if (OB_FAIL(append(map_info.equal_param_map_, context.equal_param_info_))) { + LOG_WARN("failed to append exprs", K(ret)); + } else if (OB_FAIL(matched_items.add_member(i))) { + LOG_WARN("failed to add member", K(ret)); + } else { + match_count++; + condition_map.at(i) = i; + } } } } diff --git a/src/sql/rewrite/ob_stmt_comparer.h b/src/sql/rewrite/ob_stmt_comparer.h index 6c27ebae7b..19bdbab865 100644 --- a/src/sql/rewrite/ob_stmt_comparer.h +++ b/src/sql/rewrite/ob_stmt_comparer.h @@ -219,10 +219,12 @@ public: const ObDMLStmt *second, ObStmtMapInfo &map_info); + /* is_strict_select_list = true, it requerys same order select list between two stmts. */ static int check_stmt_containment(const ObDMLStmt *first, const ObDMLStmt *second, ObStmtMapInfo &map_info, - QueryRelation &relation); + QueryRelation &relation, + bool is_strict_select_list = false); static int compute_conditions_map(const ObDMLStmt *first, const ObDMLStmt *second, @@ -230,7 +232,8 @@ public: const ObIArray &second_exprs, ObStmtMapInfo &map_info, ObIArray &condition_map, - int64_t &match_count); + int64_t &match_count, + bool is_same_by_order = false); static int compute_orderby_map(const ObDMLStmt *first, const ObDMLStmt *second, diff --git a/src/sql/rewrite/ob_transform_subquery_coalesce.cpp b/src/sql/rewrite/ob_transform_subquery_coalesce.cpp index c7de77b08e..4e37aca8e4 100644 --- a/src/sql/rewrite/ob_transform_subquery_coalesce.cpp +++ b/src/sql/rewrite/ob_transform_subquery_coalesce.cpp @@ -438,17 +438,12 @@ int ObTransformSubqueryCoalesce::coalesce_same_any_all_exprs(ObDMLStmt *stmt, OPT_TRACE("hint reject transform"); } else if (OB_FAIL(ObStmtComparer::check_stmt_containment(first_query_ref->get_ref_stmt(), second_query_ref->get_ref_stmt(), - map_info, relation))) { + map_info, + relation, + true))) { LOG_WARN("failed to check stmt containment", K(ret)); } else if (!map_info.is_select_item_equal_) { OPT_TRACE("stmts have different select items, can not coalesce"); - } else if (OB_FAIL(check_select_items_same(first_query_ref->get_ref_stmt(), - second_query_ref->get_ref_stmt(), - map_info, - is_select_same))) { - LOG_WARN("check select items failed", K(ret)); - } else if (!is_select_same) { - OPT_TRACE("The order of select items in two stmts is different, can not coalesce"); } else if (relation == QUERY_LEFT_SUBSET || relation == QUERY_EQUAL) { remove_index = (type == T_ANY ? j : i); OPT_TRACE("right query contain left query, will coalesce suqbeury"); @@ -785,17 +780,11 @@ int ObTransformSubqueryCoalesce::compare_any_all_subqueries(ObDMLStmt *stmt, } else if (OB_FAIL(ObStmtComparer::check_stmt_containment(second_query_ref->get_ref_stmt(), first_query_ref->get_ref_stmt(), param.map_info_, - relation))) { + relation, + true))) { LOG_WARN("failed to check stmt containment", K(ret)); } else if (!param.map_info_.is_select_item_equal_) { OPT_TRACE("stmts have different select items, can not coalesce"); - } else if (OB_FAIL(check_select_items_same(first_query_ref->get_ref_stmt(), - second_query_ref->get_ref_stmt(), - param.map_info_, - is_select_same))) { - LOG_WARN("check select items failed", K(ret)); - } else if (!is_select_same) { - OPT_TRACE("The order of select items in two stmts is different, can not coalesce"); } else if (relation == QueryRelation::QUERY_RIGHT_SUBSET || relation == QueryRelation::QUERY_EQUAL) { has_false_conds = true; @@ -2658,36 +2647,3 @@ int ObTransformSubqueryCoalesce::sort_coalesce_stmts(Ob2DArray } return ret; } - -int ObTransformSubqueryCoalesce::check_select_items_same(const ObDMLStmt *first, - const ObDMLStmt *second, - ObStmtMapInfo &map_info, - bool &is_same) -{ - int ret = OB_SUCCESS; - is_same = true; - if (OB_ISNULL(first) || OB_ISNULL(second)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null", K(ret), KP(first), KP(second)); - } else if (first->is_select_stmt() && second->is_select_stmt()) { - const ObSelectStmt *first_sel = static_cast(first); - const ObSelectStmt *second_sel = static_cast(second); - ObStmtCompareContext context(first, second, map_info, &first->get_query_ctx()->calculable_items_); - if (first_sel->get_select_item_size() != second_sel->get_select_item_size()) { - is_same = false; - } - for (int64_t i = 0; OB_SUCC(ret) && is_same && i < first_sel->get_select_item_size(); ++i) { - ObRawExpr *first_expr = first_sel->get_select_item(i).expr_; - ObRawExpr *second_expr = second_sel->get_select_item(i).expr_; - if (OB_ISNULL(first_expr) || OB_ISNULL(second_expr)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null", K(ret), KP(first_expr), KP(second_expr)); - } else if (!first_expr->same_as(*second_expr, &context)) { - is_same = false; - } - } - } else { - //do nothing - } - return ret; -} diff --git a/src/sql/rewrite/ob_transform_subquery_coalesce.h b/src/sql/rewrite/ob_transform_subquery_coalesce.h index b8c2d21bc3..78b6978379 100644 --- a/src/sql/rewrite/ob_transform_subquery_coalesce.h +++ b/src/sql/rewrite/ob_transform_subquery_coalesce.h @@ -236,12 +236,6 @@ private: int add_coalesce_stmts(const ObIArray &stms); int sort_coalesce_stmts(Ob2DArray &coalesce_stmts); - - int check_select_items_same(const ObDMLStmt *first, - const ObDMLStmt *second, - ObStmtMapInfo &map_info, - bool &is_same); - private: ObQueryRefRawExpr * get_exists_query_expr(ObRawExpr *expr); diff --git a/tools/deploy/mysql_test/test_suite/subquery/r/mysql/optimizer_subquery_bug.result b/tools/deploy/mysql_test/test_suite/subquery/r/mysql/optimizer_subquery_bug.result index 1926a7f725..67e6aded7e 100644 --- a/tools/deploy/mysql_test/test_suite/subquery/r/mysql/optimizer_subquery_bug.result +++ b/tools/deploy/mysql_test/test_suite/subquery/r/mysql/optimizer_subquery_bug.result @@ -600,19 +600,19 @@ Query Plan -------------------------------------------------------------- |0 |HASH DISTINCT | |1 |3 | |1 |└─NESTED-LOOP JOIN CARTESIAN | |1 |3 | -|2 | ├─SUBPLAN SCAN |VIEW3|1 |3 | +|2 | ├─SUBPLAN SCAN |VIEW1|1 |3 | |3 | │ └─SCALAR GROUP BY | |1 |3 | |4 | │ └─TABLE FULL SCAN |t2 |3 |3 | |5 | └─TABLE FULL SCAN |t1 |3 |3 | ============================================================== Outputs & filters: ------------------------------------- - 0 - output([VIEW3.T_FUN_SUM(t2.b)]), filter(nil), rowset=16 - distinct([VIEW3.T_FUN_SUM(t2.b)]) - 1 - output([VIEW3.T_FUN_SUM(t2.b)]), filter(nil), rowset=16 + 0 - output([VIEW1.sum(b)]), filter(nil), rowset=16 + distinct([VIEW1.sum(b)]) + 1 - output([VIEW1.sum(b)]), filter(nil), rowset=16 conds(nil), nl_params_(nil), use_batch=false - 2 - output([VIEW3.T_FUN_SUM(t2.b)]), filter(nil), rowset=16 - access([VIEW3.T_FUN_SUM(t2.b)]) + 2 - output([VIEW1.sum(b)]), filter(nil), rowset=16 + access([VIEW1.sum(b)]) 3 - output([T_FUN_SUM(T_FUN_SUM(t2.b))]), filter([T_FUN_SUM(T_FUN_SUM(t2.b)) > cast(4, DECIMAL_INT(33, 0))], [T_FUN_SUM(T_FUN_SUM(t2.b)) > T_FUN_SUM(T_FUN_SUM(t2.b))]), rowset=16 group(nil), agg_func([T_FUN_SUM(T_FUN_SUM(t2.b))]) 4 - output([T_FUN_SUM(t2.b)]), filter(nil), rowset=16