fix several subquery coalesce bugs

This commit is contained in:
jingtaoye35
2024-02-06 21:25:13 +00:00
committed by ob-robot
parent 992e10fee1
commit 87ad15465d
4 changed files with 53 additions and 30 deletions

View File

@ -245,21 +245,39 @@ bool ObStmtCompareContext::compare_query(const ObQueryRefRawExpr &first,
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObStmtMapInfo stmt_map_info; ObStmtMapInfo stmt_map_info;
QueryRelation relation = QueryRelation::QUERY_UNCOMPARABLE; QueryRelation relation = QueryRelation::QUERY_UNCOMPARABLE;
const ObSelectStmt *first_sel = NULL;
const ObSelectStmt *second_sel = NULL;
if (&first == &second) { if (&first == &second) {
bret = true; bret = true;
} else if (first.is_set() != second.is_set() || first.is_multiset() != second.is_multiset()) { } else if (first.is_set() != second.is_set() || first.is_multiset() != second.is_multiset() ||
OB_ISNULL(first_sel = first.get_ref_stmt()) ||
OB_ISNULL(second_sel = second.get_ref_stmt())) {
bret = false; bret = false;
} else if (OB_FAIL(ObStmtComparer::check_stmt_containment(first.get_ref_stmt(), } else if (OB_FAIL(ObStmtComparer::check_stmt_containment(first_sel,
second.get_ref_stmt(), second_sel,
stmt_map_info, stmt_map_info,
relation))) { relation))) {
LOG_WARN("failed to compute stmt relationship", K(ret)); LOG_WARN("failed to compute stmt relationship", K(ret));
err_code_ = ret; err_code_ = ret;
} else if (stmt_map_info.is_select_item_equal_ && QueryRelation::QUERY_EQUAL == relation) { } else if (stmt_map_info.is_select_item_equal_ && QueryRelation::QUERY_EQUAL == relation) {
bret = true; bool is_same = true;
if (OB_FAIL(append(equal_param_info_, stmt_map_info.equal_param_map_))) { for (int64_t i = 0; OB_SUCC(ret) && is_same && i < first_sel->get_select_item_size(); ++i) {
LOG_WARN("failed to append equal param", K(ret)); ObRawExpr *first_expr = first_sel->get_select_item(i).expr_;
err_code_ = ret; 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;
}
} }
} }
return bret; return bret;

View File

@ -255,7 +255,8 @@ int ObTransformSimplifySubquery::is_subquery_to_expr_valid(const ObSelectStmt *s
&& 0 == stmt->get_having_expr_size() && 0 == stmt->get_having_expr_size()
&& !stmt->has_limit() && !stmt->has_limit()
&& !stmt->is_hierarchical_query() && !stmt->is_hierarchical_query()
&& !stmt->is_set_stmt()) { && !stmt->is_set_stmt()
&& !stmt->has_sequence()) {
is_valid = true; is_valid = true;
} }
if (OB_SUCC(ret) && is_valid) { if (OB_SUCC(ret) && is_valid) {

View File

@ -736,6 +736,10 @@ int ObTransformSubqueryCoalesce::check_conditions_validity(ObDMLStmt *stmt,
return ret; return ret;
} }
/* do coalesce:
* (1). in (query_1) and not in (query_2), query_1 equals to query_2
* (2). in (query_1) and not in (query_2), query_1 is subset of query_2
*/
int ObTransformSubqueryCoalesce::compare_any_all_subqueries(ObDMLStmt *stmt, int ObTransformSubqueryCoalesce::compare_any_all_subqueries(ObDMLStmt *stmt,
TransformParam &param, TransformParam &param,
ObIArray<TransformParam> &trans_params, ObIArray<TransformParam> &trans_params,
@ -786,9 +790,9 @@ int ObTransformSubqueryCoalesce::compare_any_all_subqueries(ObDMLStmt *stmt,
} else if (!param.map_info_.is_select_item_equal_) { } else if (!param.map_info_.is_select_item_equal_) {
OPT_TRACE("stmts have different select items, can not coalesce"); OPT_TRACE("stmts have different select items, can not coalesce");
} else if (OB_FAIL(check_select_items_same(first_query_ref->get_ref_stmt(), } else if (OB_FAIL(check_select_items_same(first_query_ref->get_ref_stmt(),
second_query_ref->get_ref_stmt(), second_query_ref->get_ref_stmt(),
param.map_info_, param.map_info_,
is_select_same))) { is_select_same))) {
LOG_WARN("check select items failed", K(ret)); LOG_WARN("check select items failed", K(ret));
} else if (!is_select_same) { } else if (!is_select_same) {
OPT_TRACE("The order of select items in two stmts is different, can not coalesce"); OPT_TRACE("The order of select items in two stmts is different, can not coalesce");
@ -800,21 +804,21 @@ int ObTransformSubqueryCoalesce::compare_any_all_subqueries(ObDMLStmt *stmt,
if (OB_FAIL(trans_params.push_back(param))) { if (OB_FAIL(trans_params.push_back(param))) {
LOG_WARN("failed to push back transform param", K(ret)); LOG_WARN("failed to push back transform param", K(ret));
} else if (OB_FAIL(add_coalesce_stmt(first_query_ref->get_ref_stmt(), } else if (OB_FAIL(add_coalesce_stmt(first_query_ref->get_ref_stmt(),
second_query_ref->get_ref_stmt()))) { second_query_ref->get_ref_stmt()))) {
LOG_WARN("failed to add coalesce stmts", K(ret)); LOG_WARN("failed to add coalesce stmts", K(ret));
} else { } else {
OPT_TRACE("left stmt contain right stmt, will coalesce"); OPT_TRACE("all stmt contain any stmt, will coalesce");
} }
} else if (can_coalesce && relation == QUERY_LEFT_SUBSET) { } else if (can_coalesce && relation == QUERY_LEFT_SUBSET) {
if (OB_FAIL(trans_params.push_back(param))) { // is_used = true;
LOG_WARN("failed to push back transform param", K(ret)); // if (OB_FAIL(trans_params.push_back(param))) {
} else if (OB_FAIL(add_coalesce_stmt(first_query_ref->get_ref_stmt(), // LOG_WARN("failed to push back transform param", K(ret));
second_query_ref->get_ref_stmt()))) { // } else if (OB_FAIL(add_coalesce_stmt(first_query_ref->get_ref_stmt(),
LOG_WARN("failed to add coalesce stmts", K(ret)); // second_query_ref->get_ref_stmt()))) {
} else { // LOG_WARN("failed to add coalesce stmts", K(ret));
is_used = true; // } else {
OPT_TRACE("right stmt contain left stmt, will coalesce"); // OPT_TRACE("any stmt contain all stmt, will coalesce");
} // }
} else { } else {
OPT_TRACE("stmt not contain each other, will not coalesce"); OPT_TRACE("stmt not contain each other, will not coalesce");
} }
@ -1765,7 +1769,7 @@ int ObTransformSubqueryCoalesce::get_subquery_assign_exprs(ObIArray<ObRawExpr*>
LOG_WARN("unexpect null stmt", K(ret)); LOG_WARN("unexpect null stmt", K(ret));
} else if (!query_ref_expr->is_scalar()) { } else if (!query_ref_expr->is_scalar()) {
//do nothing //do nothing
} else if (stmt->has_limit() || stmt->has_distinct() || stmt->is_set_stmt()) { } else if (stmt->has_limit() || stmt->has_distinct() || stmt->is_set_stmt() || stmt->has_sequence()) {
//stmt can not coalesce,do nothing //stmt can not coalesce,do nothing
} else if (ObOptimizerUtil::find_item(subqueries, stmt)) { } else if (ObOptimizerUtil::find_item(subqueries, stmt)) {
//do nothing //do nothing
@ -1784,7 +1788,7 @@ int ObTransformSubqueryCoalesce::get_subquery_assign_exprs(ObIArray<ObRawExpr*>
if (OB_ISNULL(stmt)) { if (OB_ISNULL(stmt)) {
ret = OB_ERR_UNEXPECTED; ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect null stmt", K(ret)); LOG_WARN("unexpect null stmt", K(ret));
} else if (stmt->has_limit() || stmt->has_distinct() || stmt->is_set_stmt()) { } else if (stmt->has_limit() || stmt->has_distinct() || stmt->is_set_stmt() || stmt->has_sequence()) {
//stmt can not coalesce,do nothing //stmt can not coalesce,do nothing
} else if (ObOptimizerUtil::find_item(subqueries, stmt)) { } else if (ObOptimizerUtil::find_item(subqueries, stmt)) {
//do nothing //do nothing

View File

@ -600,19 +600,19 @@ Query Plan
-------------------------------------------------------------- --------------------------------------------------------------
|0 |HASH DISTINCT | |1 |3 | |0 |HASH DISTINCT | |1 |3 |
|1 |└─NESTED-LOOP JOIN CARTESIAN | |1 |3 | |1 |└─NESTED-LOOP JOIN CARTESIAN | |1 |3 |
|2 | ├─SUBPLAN SCAN |VIEW1|1 |3 | |2 | ├─SUBPLAN SCAN |VIEW3|1 |3 |
|3 | │ └─SCALAR GROUP BY | |1 |3 | |3 | │ └─SCALAR GROUP BY | |1 |3 |
|4 | │ └─TABLE FULL SCAN |t2 |3 |3 | |4 | │ └─TABLE FULL SCAN |t2 |3 |3 |
|5 | └─TABLE FULL SCAN |t1 |3 |3 | |5 | └─TABLE FULL SCAN |t1 |3 |3 |
============================================================== ==============================================================
Outputs & filters: Outputs & filters:
------------------------------------- -------------------------------------
0 - output([VIEW1.sum(b)]), filter(nil), rowset=16 0 - output([VIEW3.T_FUN_SUM(t2.b)]), filter(nil), rowset=16
distinct([VIEW1.sum(b)]) distinct([VIEW3.T_FUN_SUM(t2.b)])
1 - output([VIEW1.sum(b)]), filter(nil), rowset=16 1 - output([VIEW3.T_FUN_SUM(t2.b)]), filter(nil), rowset=16
conds(nil), nl_params_(nil), use_batch=false conds(nil), nl_params_(nil), use_batch=false
2 - output([VIEW1.sum(b)]), filter(nil), rowset=16 2 - output([VIEW3.T_FUN_SUM(t2.b)]), filter(nil), rowset=16
access([VIEW1.sum(b)]) access([VIEW3.T_FUN_SUM(t2.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 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))]) group(nil), agg_func([T_FUN_SUM(T_FUN_SUM(t2.b))])
4 - output([T_FUN_SUM(t2.b)]), filter(nil), rowset=16 4 - output([T_FUN_SUM(t2.b)]), filter(nil), rowset=16