Fix subquery coalesce bug
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user