fix a compare_query bug
This commit is contained in:
		| @ -256,28 +256,15 @@ bool ObStmtCompareContext::compare_query(const ObQueryRefRawExpr &first, | ||||
|   } else if (OB_FAIL(ObStmtComparer::check_stmt_containment(first_sel, | ||||
|                                                             second_sel, | ||||
|                                                             stmt_map_info, | ||||
|                                                             relation))) { | ||||
|                                                             relation, | ||||
|                                                             true))) { | ||||
|     LOG_WARN("failed to compute stmt relationship", K(ret)); | ||||
|     err_code_ = ret; | ||||
|   } else if (stmt_map_info.is_select_item_equal_ && QueryRelation::QUERY_EQUAL == relation) { | ||||
|     bool is_same = true; | ||||
|     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)); | ||||
|         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; | ||||
|       } | ||||
|     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; | ||||
| @ -399,7 +386,8 @@ int ObStmtComparer::is_same_from(const ObDMLStmt *first, | ||||
| int ObStmtComparer::check_stmt_containment(const ObDMLStmt *first, | ||||
|                                            const ObDMLStmt *second, | ||||
|                                            ObStmtMapInfo &map_info, | ||||
|                                            QueryRelation &relation) | ||||
|                                            QueryRelation &relation, | ||||
|                                            bool is_strict_select_list) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   int64_t first_count = 0; | ||||
| @ -682,7 +670,8 @@ int ObStmtComparer::check_stmt_containment(const ObDMLStmt *first, | ||||
|                                                 second_exprs, | ||||
|                                                 map_info, | ||||
|                                                 map_info.select_item_map_, | ||||
|                                                 match_count))) { | ||||
|                                                 match_count, | ||||
|                                                 is_strict_select_list))) { | ||||
|         LOG_WARN("failed to compute output expr map", K(ret)); | ||||
|       } else if (match_count == first_exprs.count() && match_count == second_exprs.count()) { | ||||
|         map_info.is_select_item_equal_ = true; | ||||
| @ -751,7 +740,8 @@ int ObStmtComparer::compute_conditions_map(const ObDMLStmt *first, | ||||
|                                            const ObIArray<ObRawExpr*> &second_exprs, | ||||
|                                            ObStmtMapInfo &map_info, | ||||
|                                            ObIArray<int64_t> &condition_map, | ||||
|                                            int64_t &match_count) | ||||
|                                            int64_t &match_count, | ||||
|                                            bool is_same_by_order) | ||||
| { | ||||
|   int ret = OB_SUCCESS; | ||||
|   ObSqlBitSet<> matched_items; | ||||
| @ -766,23 +756,45 @@ int ObStmtComparer::compute_conditions_map(const ObDMLStmt *first, | ||||
|     for (int64_t i = 0; OB_SUCC(ret) && i < first_exprs.count(); ++i) { | ||||
|       bool is_match = false; | ||||
|       condition_map.at(i) = OB_INVALID_ID; | ||||
|       for (int64_t j = 0; OB_SUCC(ret) && !is_match && j < second_exprs.count(); ++j) { | ||||
|         if (matched_items.has_member(j)) { | ||||
|           // do nothing | ||||
|         } else if (OB_FAIL(is_same_condition(first_exprs.at(i), | ||||
|                                              second_exprs.at(j), | ||||
|                                              context, | ||||
|                                              is_match))) { | ||||
|           LOG_WARN("failed to check is condition equal", K(ret)); | ||||
|         } else if (!is_match) { | ||||
|           // do nothing | ||||
|         } else if (OB_FAIL(append(map_info.equal_param_map_, context.equal_param_info_))) { | ||||
|           LOG_WARN("failed to append exprs", K(ret)); | ||||
|         } else if (OB_FAIL(matched_items.add_member(j))) { | ||||
|           LOG_WARN("failed to add member", K(ret)); | ||||
|         } else { | ||||
|           match_count++; | ||||
|           condition_map.at(i) = j; | ||||
|       if (!is_same_by_order) { | ||||
|         // is same to any one | ||||
|         for (int64_t j = 0; OB_SUCC(ret) && !is_match && j < second_exprs.count(); ++j) { | ||||
|           if (matched_items.has_member(j)) { | ||||
|             // do nothing | ||||
|           } else if (OB_FAIL(is_same_condition(first_exprs.at(i), | ||||
|                                               second_exprs.at(j), | ||||
|                                               context, | ||||
|                                               is_match))) { | ||||
|             LOG_WARN("failed to check is condition equal", K(ret)); | ||||
|           } else if (!is_match) { | ||||
|             // do nothing | ||||
|           } else if (OB_FAIL(append(map_info.equal_param_map_, context.equal_param_info_))) { | ||||
|             LOG_WARN("failed to append exprs", K(ret)); | ||||
|           } else if (OB_FAIL(matched_items.add_member(j))) { | ||||
|             LOG_WARN("failed to add member", K(ret)); | ||||
|           } else { | ||||
|             match_count++; | ||||
|             condition_map.at(i) = j; | ||||
|           } | ||||
|         } | ||||
|       } else { | ||||
|         // is same by order | ||||
|         if (i < second_exprs.count()) { | ||||
|           if (OB_FAIL(is_same_condition(first_exprs.at(i), | ||||
|                                         second_exprs.at(i), | ||||
|                                         context, | ||||
|                                         is_match))) { | ||||
|             LOG_WARN("failed to check is condition equal", K(ret)); | ||||
|           } else if (!is_match) { | ||||
|             // do nothing | ||||
|           } else if (OB_FAIL(append(map_info.equal_param_map_, context.equal_param_info_))) { | ||||
|             LOG_WARN("failed to append exprs", K(ret)); | ||||
|           } else if (OB_FAIL(matched_items.add_member(i))) { | ||||
|             LOG_WARN("failed to add member", K(ret)); | ||||
|           } else { | ||||
|             match_count++; | ||||
|             condition_map.at(i) = i; | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
| @ -219,10 +219,12 @@ public: | ||||
|                                   const ObDMLStmt *second, | ||||
|                                   ObStmtMapInfo &map_info); | ||||
|  | ||||
|   /* is_strict_select_list = true, it requerys same order select list between two stmts. */ | ||||
|   static int check_stmt_containment(const ObDMLStmt *first, | ||||
|                                     const ObDMLStmt *second, | ||||
|                                     ObStmtMapInfo &map_info, | ||||
|                                     QueryRelation &relation); | ||||
|                                     QueryRelation &relation, | ||||
|                                     bool is_strict_select_list = false); | ||||
|  | ||||
|   static int compute_conditions_map(const ObDMLStmt *first, | ||||
|                                     const ObDMLStmt *second, | ||||
| @ -230,7 +232,8 @@ public: | ||||
|                                     const ObIArray<ObRawExpr*> &second_exprs, | ||||
|                                     ObStmtMapInfo &map_info, | ||||
|                                     ObIArray<int64_t> &condition_map, | ||||
|                                     int64_t &match_count); | ||||
|                                     int64_t &match_count, | ||||
|                                     bool is_same_by_order = false); | ||||
|  | ||||
|   static int compute_orderby_map(const ObDMLStmt *first, | ||||
|                                  const ObDMLStmt *second, | ||||
|  | ||||
| @ -438,17 +438,12 @@ int ObTransformSubqueryCoalesce::coalesce_same_any_all_exprs(ObDMLStmt *stmt, | ||||
|           OPT_TRACE("hint reject transform"); | ||||
|         } else if (OB_FAIL(ObStmtComparer::check_stmt_containment(first_query_ref->get_ref_stmt(), | ||||
|                                                                   second_query_ref->get_ref_stmt(), | ||||
|                                                                   map_info, relation))) { | ||||
|                                                                   map_info, | ||||
|                                                                   relation, | ||||
|                                                                   true))) { | ||||
|           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"); | ||||
| @ -785,17 +780,11 @@ int ObTransformSubqueryCoalesce::compare_any_all_subqueries(ObDMLStmt *stmt, | ||||
|   } else if (OB_FAIL(ObStmtComparer::check_stmt_containment(second_query_ref->get_ref_stmt(), | ||||
|                                                             first_query_ref->get_ref_stmt(), | ||||
|                                                             param.map_info_, | ||||
|                                                             relation))) { | ||||
|                                                             relation, | ||||
|                                                             true))) { | ||||
|     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; | ||||
| @ -2658,36 +2647,3 @@ 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; | ||||
| } | ||||
|  | ||||
| @ -236,12 +236,6 @@ private: | ||||
|   int add_coalesce_stmts(const ObIArray<ObSelectStmt*> &stms); | ||||
|  | ||||
|   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); | ||||
|  | ||||
| @ -600,19 +600,19 @@ Query Plan | ||||
| -------------------------------------------------------------- | ||||
| |0 |HASH DISTINCT                |     |1       |3           | | ||||
| |1 |└─NESTED-LOOP JOIN CARTESIAN |     |1       |3           | | ||||
| |2 |  ├─SUBPLAN SCAN             |VIEW3|1       |3           | | ||||
| |2 |  ├─SUBPLAN SCAN             |VIEW1|1       |3           | | ||||
| |3 |  │ └─SCALAR GROUP BY        |     |1       |3           | | ||||
| |4 |  │   └─TABLE FULL SCAN      |t2   |3       |3           | | ||||
| |5 |  └─TABLE FULL SCAN          |t1   |3       |3           | | ||||
| ============================================================== | ||||
| Outputs & filters: | ||||
| ------------------------------------- | ||||
|   0 - output([VIEW3.T_FUN_SUM(t2.b)]), filter(nil), rowset=16 | ||||
|       distinct([VIEW3.T_FUN_SUM(t2.b)]) | ||||
|   1 - output([VIEW3.T_FUN_SUM(t2.b)]), filter(nil), rowset=16 | ||||
|   0 - output([VIEW1.sum(b)]), filter(nil), rowset=16 | ||||
|       distinct([VIEW1.sum(b)]) | ||||
|   1 - output([VIEW1.sum(b)]), filter(nil), rowset=16 | ||||
|       conds(nil), nl_params_(nil), use_batch=false | ||||
|   2 - output([VIEW3.T_FUN_SUM(t2.b)]), filter(nil), rowset=16 | ||||
|       access([VIEW3.T_FUN_SUM(t2.b)]) | ||||
|   2 - output([VIEW1.sum(b)]), filter(nil), rowset=16 | ||||
|       access([VIEW1.sum(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 | ||||
|       group(nil), agg_func([T_FUN_SUM(T_FUN_SUM(t2.b))]) | ||||
|   4 - output([T_FUN_SUM(t2.b)]), filter(nil), rowset=16 | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 jingtaoye35
					jingtaoye35