fix a compare_query bug
This commit is contained in:
@ -256,30 +256,17 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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,6 +756,8 @@ 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;
|
||||
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
|
||||
@ -785,6 +777,26 @@ int ObStmtComparer::compute_conditions_map(const ObDMLStmt *first,
|
||||
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;
|
||||
|
||||
@ -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