Fix subquery coalesce bug

This commit is contained in:
2149
2023-08-17 10:43:35 +00:00
committed by ob-robot
parent c7cf2b9586
commit 4fb42a22e8
2 changed files with 57 additions and 1 deletions

View File

@ -91,7 +91,7 @@ int ObTransformSubqueryCoalesce::transform_one_stmt(common::ObIArray<ObParentDML
} else if (OB_ISNULL(trans_stmt)) {
// do nothing
} else if (OB_FAIL(accept_transform(parent_stmts, stmt, trans_stmt, false, false, is_happened))) {
LOG_WARN("failed to accept transform", K(ret));
LOG_WARN("failed to accept transform", K(ret), KPC(trans_stmt));
} else if (!is_happened) {
// do nothing
} else if (OB_FAIL(append(ctx_->equal_param_constraints_, cost_based_equal_infos))) {
@ -401,6 +401,7 @@ int ObTransformSubqueryCoalesce::coalesce_same_any_all_exprs(ObDMLStmt *stmt,
is_happened = false;
bool force_trans = false;
bool force_no_trans = false;
bool is_select_same = false;
if (OB_ISNULL(stmt) || OB_ISNULL(ctx_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("params have null", K(ret), K(stmt), K(ctx_));
@ -441,6 +442,13 @@ int ObTransformSubqueryCoalesce::coalesce_same_any_all_exprs(ObDMLStmt *stmt,
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");
@ -746,6 +754,7 @@ int ObTransformSubqueryCoalesce::compare_any_all_subqueries(ObDMLStmt *stmt,
ObQueryRefRawExpr* first_query_ref = get_any_all_query_expr(param.any_expr_);
ObRawExpr* second_left_expr = get_any_all_left_hand_expr(param.all_expr_);
ObQueryRefRawExpr* second_query_ref = get_any_all_query_expr(param.all_expr_);
bool is_select_same = false;
OPT_TRACE("try to coalesce any/all subquery:");
OPT_TRACE("any expr:", param.any_expr_);
OPT_TRACE("all expr:", param.all_expr_);
@ -774,6 +783,15 @@ int ObTransformSubqueryCoalesce::compare_any_all_subqueries(ObDMLStmt *stmt,
param.map_info_,
relation))) {
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;
@ -2635,3 +2653,36 @@ int ObTransformSubqueryCoalesce::sort_coalesce_stmts(Ob2DArray<CoalesceStmts *>
}
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<const ObSelectStmt *>(first);
const ObSelectStmt *second_sel = static_cast<const ObSelectStmt *>(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;
}

View File

@ -237,6 +237,11 @@ private:
int sort_coalesce_stmts(Ob2DArray<CoalesceStmts *> &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);