diff --git a/src/sql/resolver/dml/ob_dml_stmt.cpp b/src/sql/resolver/dml/ob_dml_stmt.cpp index 202631c778..831482d756 100644 --- a/src/sql/resolver/dml/ob_dml_stmt.cpp +++ b/src/sql/resolver/dml/ob_dml_stmt.cpp @@ -4414,8 +4414,10 @@ int ObDMLStmt::do_formalize_query_ref_exprs_pre() ObQueryRefRawExpr *ref_query = NULL; ObExecParamRawExpr *exec_param = NULL; ObSEArray ref_exprs; + ObSEArray ref_exec_idxs; for (int64_t j = 0; OB_SUCC(ret) && j < subquery_exprs_.count(); ++j) { ref_exprs.reuse(); + ref_exec_idxs.reuse(); if (OB_ISNULL(ref_query = subquery_exprs_.at(j))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null", K(ret)); @@ -4430,9 +4432,11 @@ int ObDMLStmt::do_formalize_query_ref_exprs_pre() } else if (ObOptimizerUtil::find_item(ref_exprs, exec_param->get_ref_expr(), &idx)) { - exec_param->set_ref_expr(ref_exprs.at(idx)); + exec_param->set_ref_expr(ref_query->get_exec_param(ref_exec_idxs.at(idx))); } else if (OB_FAIL(ref_exprs.push_back(exec_param->get_ref_expr()))) { LOG_WARN("failed to push back ref exprs"); + } else if (OB_FAIL(ref_exec_idxs.push_back(i))) { + LOG_WARN("failed to push back ref exec idxs", K(ret)); } } } diff --git a/src/sql/resolver/dml/ob_select_resolver.cpp b/src/sql/resolver/dml/ob_select_resolver.cpp index 13185c7574..88ffbed691 100644 --- a/src/sql/resolver/dml/ob_select_resolver.cpp +++ b/src/sql/resolver/dml/ob_select_resolver.cpp @@ -6615,6 +6615,8 @@ int ObSelectResolver::resolve_shared_order_item(OrderItem &order_item, ObSelectS OB_ISNULL(params_.query_ctx_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null pointer", K(ret)); + } else if (select_stmt->is_order_siblings()) { + // do noting } else if (OB_FAIL(select_stmt->get_select_exprs(select_exprs))) { LOG_WARN("failed to get select exprs", K(ret)); } else if (ObOptimizerUtil::find_item(select_exprs, order_item.expr_)) { diff --git a/src/sql/rewrite/ob_transform_simplify_subquery.cpp b/src/sql/rewrite/ob_transform_simplify_subquery.cpp index 18bdece06d..45ddf5a73d 100644 --- a/src/sql/rewrite/ob_transform_simplify_subquery.cpp +++ b/src/sql/rewrite/ob_transform_simplify_subquery.cpp @@ -2162,6 +2162,7 @@ int ObTransformSimplifySubquery::check_can_trans_as_exists(ObRawExpr* expr, bool int ret = OB_SUCCESS; ObQueryRefRawExpr* right_hand = NULL; ObRawExpr* left_hand = NULL; + bool dummy = false; is_valid = false; if (OB_ISNULL(expr)) { ret = OB_ERR_UNEXPECTED; @@ -2188,17 +2189,22 @@ int ObTransformSimplifySubquery::check_can_trans_as_exists(ObRawExpr* expr, bool // do nothing } else if (OB_FAIL(check_stmt_can_trans_as_exists(right_hand->get_ref_stmt(), !right_hand->get_exec_params().empty(), + dummy, is_valid))) { LOG_WARN("failed to check stmt can trans as exists", K(ret)); } return ret; } -int ObTransformSimplifySubquery::check_stmt_can_trans_as_exists(ObSelectStmt *stmt, bool is_correlated, bool &is_valid) +int ObTransformSimplifySubquery::check_stmt_can_trans_as_exists(ObSelectStmt *stmt, + bool is_correlated, + bool &match_index, + bool &is_valid) { int ret = OB_SUCCESS; bool contain_rownum = false; is_valid = false; + match_index = false; if (OB_ISNULL(stmt) || OB_ISNULL(ctx_)) { ret = OB_ERR_UNEXPECTED; @@ -2209,6 +2215,7 @@ int ObTransformSimplifySubquery::check_stmt_can_trans_as_exists(ObSelectStmt *st stmt->has_limit()) { // do nothing } else if (stmt->is_set_stmt()) { + bool has_index_matched = false; if (stmt->is_recursive_union()) { } else if (stmt->get_set_op() == ObSelectStmt::EXCEPT) { if (OB_UNLIKELY(stmt->get_set_query().empty())) { @@ -2216,18 +2223,29 @@ int ObTransformSimplifySubquery::check_stmt_can_trans_as_exists(ObSelectStmt *st LOG_WARN("get except set query is empty", K(ret)); } else if (OB_FAIL(SMART_CALL(check_stmt_can_trans_as_exists(stmt->get_set_query(0), is_correlated, + has_index_matched, is_valid)))) { LOG_WARN("failted to check stmt can trans as exists", K(ret)); + } else { + match_index = has_index_matched; + is_valid = has_index_matched && is_valid; } } else { is_valid = true; for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < stmt->get_set_query().count(); ++i) { + has_index_matched = false; if (OB_FAIL(SMART_CALL(check_stmt_can_trans_as_exists(stmt->get_set_query(i), is_correlated, + has_index_matched, is_valid)))) { LOG_WARN("failted to check stmt can trans as exists", K(ret)); + } else if (has_index_matched) { + match_index = has_index_matched; } } + if (OB_SUCC(ret)) { + is_valid = match_index && is_valid; + } } } else if (stmt->is_contains_assignment() || stmt->is_hierarchical_query() || @@ -2266,6 +2284,8 @@ int ObTransformSimplifySubquery::check_stmt_can_trans_as_exists(ObSelectStmt *st &equal_sets, &const_exprs))) { LOG_WARN("failed to check is match index prefix", K(ret)); + } else if (is_valid) { + match_index = true; } } } diff --git a/src/sql/rewrite/ob_transform_simplify_subquery.h b/src/sql/rewrite/ob_transform_simplify_subquery.h index 5efa493d18..2d7644643c 100644 --- a/src/sql/rewrite/ob_transform_simplify_subquery.h +++ b/src/sql/rewrite/ob_transform_simplify_subquery.h @@ -204,7 +204,10 @@ private: ObNotNullContext *not_null_ctx, bool &trans_happened); int check_can_trans_as_exists(ObRawExpr* expr, bool is_bool_expr, bool &is_valid); - int check_stmt_can_trans_as_exists(ObSelectStmt *stmt, bool is_correlated, bool &is_valid); + int check_stmt_can_trans_as_exists(ObSelectStmt *stmt, + bool is_correlated, + bool &match_index, + bool &is_valid); int query_cmp_to_exists_value_cmp(ObItemType type, bool is_with_all, ObItemType& new_type); int add_limit_for_any_all_subquery(ObRawExpr *stmt,bool &trans_happened); int prepare_trans_any_all_as_exists(ObQueryRefRawExpr* expr, ObSelectStmt *&trans_stmt);