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,
|
} 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;
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user