fix a compare_query bug

This commit is contained in:
jingtaoye35
2023-11-27 14:42:38 +00:00
committed by ob-robot
parent f3729e4130
commit fc7afe549f
5 changed files with 67 additions and 102 deletions

View File

@ -256,30 +256,17 @@ bool ObStmtCompareContext::compare_query(const ObQueryRefRawExpr &first,
} else if (OB_FAIL(ObStmtComparer::check_stmt_containment(first_sel, } else if (OB_FAIL(ObStmtComparer::check_stmt_containment(first_sel,
second_sel, second_sel,
stmt_map_info, stmt_map_info,
relation))) { relation,
true))) {
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) {
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; bret = true;
if (OB_FAIL(append(equal_param_info_, stmt_map_info.equal_param_map_))) { if (OB_FAIL(append(equal_param_info_, stmt_map_info.equal_param_map_))) {
LOG_WARN("failed to append equal param", K(ret)); LOG_WARN("failed to append equal param", K(ret));
err_code_ = ret; err_code_ = ret;
} }
} }
}
return bret; return bret;
} }
@ -399,7 +386,8 @@ int ObStmtComparer::is_same_from(const ObDMLStmt *first,
int ObStmtComparer::check_stmt_containment(const ObDMLStmt *first, int ObStmtComparer::check_stmt_containment(const ObDMLStmt *first,
const ObDMLStmt *second, const ObDMLStmt *second,
ObStmtMapInfo &map_info, ObStmtMapInfo &map_info,
QueryRelation &relation) QueryRelation &relation,
bool is_strict_select_list)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
int64_t first_count = 0; int64_t first_count = 0;
@ -682,7 +670,8 @@ int ObStmtComparer::check_stmt_containment(const ObDMLStmt *first,
second_exprs, second_exprs,
map_info, map_info,
map_info.select_item_map_, map_info.select_item_map_,
match_count))) { match_count,
is_strict_select_list))) {
LOG_WARN("failed to compute output expr map", K(ret)); LOG_WARN("failed to compute output expr map", K(ret));
} else if (match_count == first_exprs.count() && match_count == second_exprs.count()) { } else if (match_count == first_exprs.count() && match_count == second_exprs.count()) {
map_info.is_select_item_equal_ = true; map_info.is_select_item_equal_ = true;
@ -751,7 +740,8 @@ int ObStmtComparer::compute_conditions_map(const ObDMLStmt *first,
const ObIArray<ObRawExpr*> &second_exprs, const ObIArray<ObRawExpr*> &second_exprs,
ObStmtMapInfo &map_info, ObStmtMapInfo &map_info,
ObIArray<int64_t> &condition_map, ObIArray<int64_t> &condition_map,
int64_t &match_count) int64_t &match_count,
bool is_same_by_order)
{ {
int ret = OB_SUCCESS; int ret = OB_SUCCESS;
ObSqlBitSet<> matched_items; ObSqlBitSet<> matched_items;
@ -766,6 +756,8 @@ int ObStmtComparer::compute_conditions_map(const ObDMLStmt *first,
for (int64_t i = 0; OB_SUCC(ret) && i < first_exprs.count(); ++i) { for (int64_t i = 0; OB_SUCC(ret) && i < first_exprs.count(); ++i) {
bool is_match = false; bool is_match = false;
condition_map.at(i) = OB_INVALID_ID; condition_map.at(i) = OB_INVALID_ID;
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) { for (int64_t j = 0; OB_SUCC(ret) && !is_match && j < second_exprs.count(); ++j) {
if (matched_items.has_member(j)) { if (matched_items.has_member(j)) {
// do nothing // do nothing
@ -785,6 +777,26 @@ int ObStmtComparer::compute_conditions_map(const ObDMLStmt *first,
condition_map.at(i) = j; 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;
}
}
}
} }
} }
return ret; return ret;

View File

@ -219,10 +219,12 @@ public:
const ObDMLStmt *second, const ObDMLStmt *second,
ObStmtMapInfo &map_info); 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, static int check_stmt_containment(const ObDMLStmt *first,
const ObDMLStmt *second, const ObDMLStmt *second,
ObStmtMapInfo &map_info, ObStmtMapInfo &map_info,
QueryRelation &relation); QueryRelation &relation,
bool is_strict_select_list = false);
static int compute_conditions_map(const ObDMLStmt *first, static int compute_conditions_map(const ObDMLStmt *first,
const ObDMLStmt *second, const ObDMLStmt *second,
@ -230,7 +232,8 @@ public:
const ObIArray<ObRawExpr*> &second_exprs, const ObIArray<ObRawExpr*> &second_exprs,
ObStmtMapInfo &map_info, ObStmtMapInfo &map_info,
ObIArray<int64_t> &condition_map, 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, static int compute_orderby_map(const ObDMLStmt *first,
const ObDMLStmt *second, const ObDMLStmt *second,

View File

@ -438,17 +438,12 @@ int ObTransformSubqueryCoalesce::coalesce_same_any_all_exprs(ObDMLStmt *stmt,
OPT_TRACE("hint reject transform"); OPT_TRACE("hint reject transform");
} else if (OB_FAIL(ObStmtComparer::check_stmt_containment(first_query_ref->get_ref_stmt(), } else if (OB_FAIL(ObStmtComparer::check_stmt_containment(first_query_ref->get_ref_stmt(),
second_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)); LOG_WARN("failed to check stmt containment", K(ret));
} else if (!map_info.is_select_item_equal_) { } else if (!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(),
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) { } else if (relation == QUERY_LEFT_SUBSET || relation == QUERY_EQUAL) {
remove_index = (type == T_ANY ? j : i); remove_index = (type == T_ANY ? j : i);
OPT_TRACE("right query contain left query, will coalesce suqbeury"); 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(), } else if (OB_FAIL(ObStmtComparer::check_stmt_containment(second_query_ref->get_ref_stmt(),
first_query_ref->get_ref_stmt(), first_query_ref->get_ref_stmt(),
param.map_info_, param.map_info_,
relation))) { relation,
true))) {
LOG_WARN("failed to check stmt containment", K(ret)); LOG_WARN("failed to check stmt containment", K(ret));
} 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(),
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 || } else if (relation == QueryRelation::QUERY_RIGHT_SUBSET ||
relation == QueryRelation::QUERY_EQUAL) { relation == QueryRelation::QUERY_EQUAL) {
has_false_conds = true; has_false_conds = true;
@ -2658,36 +2647,3 @@ int ObTransformSubqueryCoalesce::sort_coalesce_stmts(Ob2DArray<CoalesceStmts *>
} }
return ret; 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;
}

View File

@ -236,12 +236,6 @@ private:
int add_coalesce_stmts(const ObIArray<ObSelectStmt*> &stms); int add_coalesce_stmts(const ObIArray<ObSelectStmt*> &stms);
int sort_coalesce_stmts(Ob2DArray<CoalesceStmts *> &coalesce_stmts); 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: private:
ObQueryRefRawExpr * get_exists_query_expr(ObRawExpr *expr); ObQueryRefRawExpr * get_exists_query_expr(ObRawExpr *expr);

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 |VIEW3|1 |3 | |2 | ├─SUBPLAN SCAN |VIEW1|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([VIEW3.T_FUN_SUM(t2.b)]), filter(nil), rowset=16 0 - output([VIEW1.sum(b)]), filter(nil), rowset=16
distinct([VIEW3.T_FUN_SUM(t2.b)]) distinct([VIEW1.sum(b)])
1 - output([VIEW3.T_FUN_SUM(t2.b)]), filter(nil), rowset=16 1 - output([VIEW1.sum(b)]), filter(nil), rowset=16
conds(nil), nl_params_(nil), use_batch=false conds(nil), nl_params_(nil), use_batch=false
2 - output([VIEW3.T_FUN_SUM(t2.b)]), filter(nil), rowset=16 2 - output([VIEW1.sum(b)]), filter(nil), rowset=16
access([VIEW3.T_FUN_SUM(t2.b)]) 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 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