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
	 jingtaoye35
					jingtaoye35