fix several subquery coalesce bugs
This commit is contained in:
@ -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;
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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 ¶m,
|
TransformParam ¶m,
|
||||||
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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user