diff --git a/src/sql/optimizer/ob_access_path_estimation.cpp b/src/sql/optimizer/ob_access_path_estimation.cpp index 30a887db2..41175ee6a 100644 --- a/src/sql/optimizer/ob_access_path_estimation.cpp +++ b/src/sql/optimizer/ob_access_path_estimation.cpp @@ -2010,7 +2010,7 @@ int ObAccessPathEstimation::storage_estimate_range_rowcount(ObOptimizerContext & } } - if (OB_FAIL(ret)) { + if (OB_FAIL(ret) || need_fallback) { } else if (OB_ISNULL(ranges)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ranges is null", K(ret)); diff --git a/src/sql/resolver/dml/ob_dml_resolver.cpp b/src/sql/resolver/dml/ob_dml_resolver.cpp index 0296f94c3..d649d298c 100755 --- a/src/sql/resolver/dml/ob_dml_resolver.cpp +++ b/src/sql/resolver/dml/ob_dml_resolver.cpp @@ -18889,8 +18889,11 @@ int ObDMLResolver::resolve_match_against_exprs(ObRawExpr *&expr, int ret = OB_SUCCESS; ObDMLStmt *stmt = get_stmt(); ObQuestionmarkEqualCtx check_ctx; + ObExprEqualCheckContext equal_ctx; + equal_ctx.override_const_compare_ = true; + const ParamStore *param_store = params_.param_list_; ObRawExprReplacer replacer; - if (OB_ISNULL(stmt) || OB_ISNULL(expr) || OB_ISNULL(params_.query_ctx_)) { + if (OB_ISNULL(stmt) || OB_ISNULL(expr) || OB_ISNULL(params_.query_ctx_) || OB_ISNULL(param_store)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null", K(ret), K(stmt), K(expr)); } else { @@ -18901,7 +18904,7 @@ int ObDMLResolver::resolve_match_against_exprs(ObRawExpr *&expr, ObSEArray match_exprs_on_table; bool table_on_null_side = false; bool is_simple_filter = false; - ObSEArray constraints; + ObSEArray param_constraints; if (OB_ISNULL(cur_match_expr = match_exprs.at(i))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null", K(ret)); @@ -18912,10 +18915,29 @@ int ObDMLResolver::resolve_match_against_exprs(ObRawExpr *&expr, } else if (OB_FAIL(resolve_match_against_expr(*cur_match_expr))) { LOG_WARN("failed to resolve match index", K(ret)); } else { - for (int64_t match_idx = 0; match_idx < match_exprs_on_table.count(); ++match_idx) { - if (match_exprs_on_table.at(match_idx)->same_as(*cur_match_expr, &check_ctx)) { - match_expr_on_table = static_cast(match_exprs_on_table.at(match_idx)); - break; + bool shared = false; + for (int64_t idx = 0; OB_SUCC(ret) && !shared && idx < match_exprs_on_table.count(); ++idx) { + if (match_exprs_on_table.at(idx)->same_as(*cur_match_expr, &check_ctx)) { + match_expr_on_table = static_cast(match_exprs_on_table.at(idx)); + shared = true; + } else if (match_exprs_on_table.at(idx)->same_as(*cur_match_expr, &equal_ctx)) { + match_expr_on_table = static_cast(match_exprs_on_table.at(idx)); + shared = true; + // constraints need to be added if the same_as judgement relies on specific const value + for(int64_t i = 0; OB_SUCC(ret) && i < equal_ctx.param_expr_.count(); i++) { + ObPCConstParamInfo param_info; + int64_t param_idx = equal_ctx.param_expr_.at(i).param_idx_; + if (OB_UNLIKELY(param_idx < 0 || param_idx >= param_store->count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected error", K(ret), K(param_idx), K(param_store->count())); + } else if (OB_FAIL(param_info.const_idx_.push_back(param_idx))) { + LOG_WARN("failed to push back param idx", K(ret)); + } else if (OB_FAIL(param_info.const_params_.push_back(param_store->at(param_idx)))) { + LOG_WARN("failed to push back value", K(ret)); + } else if (OB_FAIL(param_constraints.push_back(param_info))) { + LOG_WARN("failed to push back param info", K(ret)); + } + } } } } @@ -18938,6 +18960,8 @@ int ObDMLResolver::resolve_match_against_exprs(ObRawExpr *&expr, LOG_WARN("failed to replace expr", K(ret)); } else if (OB_FAIL(append(params_.query_ctx_->all_equal_param_constraints_, check_ctx.equal_pairs_))) { LOG_WARN("failed to append equal param info", K(ret)); + } else if (OB_FAIL(append(params_.query_ctx_->all_plan_const_param_constraints_, param_constraints))) { + LOG_WARN("failed to append param info", K(ret)); } } } diff --git a/src/sql/rewrite/ob_transform_simplify_subquery.cpp b/src/sql/rewrite/ob_transform_simplify_subquery.cpp index 758446ece..827b19825 100644 --- a/src/sql/rewrite/ob_transform_simplify_subquery.cpp +++ b/src/sql/rewrite/ob_transform_simplify_subquery.cpp @@ -1889,7 +1889,7 @@ int ObTransformSimplifySubquery::check_const_select(const ObSelectStmt &stmt, int ObTransformSimplifySubquery::try_trans_any_all_as_exists(ObDMLStmt *stmt, ObRawExpr *&expr, ObNotNullContext *not_null_ctx, - bool is_bool_expr, + bool used_as_condition, bool &trans_happened) { int ret = OB_SUCCESS; @@ -1901,7 +1901,7 @@ int ObTransformSimplifySubquery::try_trans_any_all_as_exists(ObDMLStmt *stmt, } else if (IS_SUBQUERY_COMPARISON_OP(expr->get_expr_type())) { if (OB_FAIL(ObTransformUtils::check_can_trans_any_all_as_exists(ctx_, expr, - is_bool_expr, + used_as_condition, true, is_valid))) { LOG_WARN("failed to check in can tras as exists", K(ret)); @@ -1965,11 +1965,14 @@ int ObTransformSimplifySubquery::try_trans_any_all_as_exists(ObDMLStmt *stmt, } } else { //check children + used_as_condition = (expr->get_expr_type() == T_OP_AND || + expr->get_expr_type() == T_OP_OR || + expr->get_expr_type() == T_OP_BOOL) ? used_as_condition : false; for (int64_t i = 0; OB_SUCC(ret) && i < expr->get_param_count(); ++i) { if (OB_FAIL(SMART_CALL(try_trans_any_all_as_exists(stmt, expr->get_param_expr(i), not_null_ctx, - false, + used_as_condition, is_happened)))) { LOG_WARN("failed to try_transform_any_all for param", K(ret)); } else { @@ -2104,7 +2107,7 @@ int ObTransformSimplifySubquery::try_trans_any_all_as_exists( ObDMLStmt *stmt, ObIArray &exprs, ObNotNullContext *not_null_cxt, - bool is_bool_expr, + bool used_as_condition, bool &trans_happened) { int ret = OB_SUCCESS; @@ -2113,7 +2116,7 @@ int ObTransformSimplifySubquery::try_trans_any_all_as_exists( if (OB_FAIL(try_trans_any_all_as_exists(stmt, exprs.at(i), not_null_cxt, - is_bool_expr, + used_as_condition, is_happened))) { LOG_WARN("failed to try trans any all as exists", K(ret)); } else { diff --git a/src/sql/rewrite/ob_transform_simplify_subquery.h b/src/sql/rewrite/ob_transform_simplify_subquery.h index b4a45359c..9a10cece8 100644 --- a/src/sql/rewrite/ob_transform_simplify_subquery.h +++ b/src/sql/rewrite/ob_transform_simplify_subquery.h @@ -194,7 +194,7 @@ private: int try_trans_any_all_as_exists(ObDMLStmt *stmt, ObRawExpr *&expr, ObNotNullContext *not_null_ctx, - bool is_bool_expr, + bool used_as_condition, bool &trans_happened); int add_limit_for_any_all_subquery(ObRawExpr *stmt,bool &trans_happened); int transform_any_all_as_exists(ObDMLStmt *stmt, bool &trans_happened); @@ -204,7 +204,7 @@ private: int try_trans_any_all_as_exists(ObDMLStmt *stmt, ObIArray &exprs, ObNotNullContext *not_null_cxt, - bool is_bool_expr, + bool used_as_condition, bool &trans_happened); int empty_table_subquery_can_be_eliminated_in_exists(ObRawExpr *expr, bool &is_valid); diff --git a/tools/deploy/mysql_test/test_suite/subquery/r/mysql/subquery.result b/tools/deploy/mysql_test/test_suite/subquery/r/mysql/subquery.result index 6e1e4e093..67316d767 100644 --- a/tools/deploy/mysql_test/test_suite/subquery/r/mysql/subquery.result +++ b/tools/deploy/mysql_test/test_suite/subquery/r/mysql/subquery.result @@ -633,7 +633,7 @@ Outputs & filters: is_index_back=false, is_global_index=false, range_key([t2.c1]), range(MIN ; MAX)always true 4 - output([t1.c1 + 1], [t2.c1], [t2.c2], [t2.c3]), filter(nil), rowset=16 - equal_conds([t2.c1 = t3.c3]), other_conds([t3.c1 > t1.c1 + 1]) + equal_conds([t3.c3 = t2.c1]), other_conds([t3.c1 > t1.c1 + 1]) merge_directions([ASC]) 5 - output([t1.c1 + 1], [t2.c1], [t2.c2], [t2.c3]), filter(nil), rowset=16 conds([lnnvl(cast(t1.c1 + 1 = t2.c2, TINYINT(-1, 0)))]), nl_params_(nil), use_batch=false