Fix stmt compare bug

This commit is contained in:
xianyu-w
2023-07-21 12:42:30 +00:00
committed by ob-robot
parent 2da1dc3e4a
commit b7f99a68c0
3 changed files with 129 additions and 2 deletions

View File

@ -596,6 +596,29 @@ int ObStmtComparer::check_stmt_containment(const ObDMLStmt *first,
}
}
// check order by exprs
if (OB_SUCC(ret) && QueryRelation::QUERY_UNCOMPARABLE != relation) {
first_count = first->get_order_item_size();
second_count = second->get_order_item_size();
if (0 == first_count && 0 == second_count) {
map_info.is_order_equal_ = true;
} else if (OB_FAIL(compute_orderby_map(first_sel,
second_sel,
first_sel->get_order_items(),
second_sel->get_order_items(),
map_info,
map_info.order_map_,
match_count))) {
LOG_WARN("failed to compute order item map", K(ret));
} else if (match_count == first_count && match_count == second_count) {
map_info.is_order_equal_ = true;
LOG_TRACE("succeed to check order item map", K(relation), K(map_info));
} else {
// The Order Item relation does not afftect the query relation
LOG_TRACE("succeed to check order item map", K(relation), K(map_info));
}
}
// check limit exprs
if (OB_SUCC(ret) && QueryRelation::QUERY_UNCOMPARABLE != relation) {
if (!first_sel->has_limit() && !second_sel->has_limit()) {
@ -738,6 +761,53 @@ int ObStmtComparer::compute_conditions_map(const ObDMLStmt *first,
return ret;
}
int ObStmtComparer::compute_orderby_map(const ObDMLStmt *first,
const ObDMLStmt *second,
const ObIArray<OrderItem> &first_orders,
const ObIArray<OrderItem> &second_orders,
ObStmtMapInfo &map_info,
ObIArray<int64_t> &order_map,
int64_t &match_count)
{
int ret = OB_SUCCESS;
ObSqlBitSet<> matched_items;
ObStmtCompareContext context(first, second, map_info, &first->get_query_ctx()->calculable_items_);
match_count = 0;
if (OB_ISNULL(first) || OB_ISNULL(second) || OB_ISNULL(first->get_query_ctx())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(first), K(second), K(ret));
} else if (OB_FAIL(order_map.prepare_allocate(first_orders.count()))) {
LOG_WARN("failed to preallocate array", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < first_orders.count(); ++i) {
bool is_match = false;
order_map.at(i) = OB_INVALID_ID;
for (int64_t j = 0; OB_SUCC(ret) && !is_match && j < second_orders.count(); ++j) {
if (matched_items.has_member(j)) {
// do nothing
} else if (first_orders.at(i).order_type_ != second_orders.at(i).order_type_) {
// do nothing
} else if (OB_FAIL(is_same_condition(first_orders.at(i).expr_,
second_orders.at(j).expr_,
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++;
order_map.at(i) = j;
}
}
}
}
return ret;
}
int ObStmtComparer::is_same_condition(const ObRawExpr *left,
const ObRawExpr *right,
ObStmtCompareContext &context,
@ -1128,7 +1198,7 @@ int ObStmtComparer::compare_table_item(const ObDMLStmt *first,
} else if (OB_FAIL(map_info.view_select_item_map_.at(first_table_index - 1).assign(ref_query_map_info.select_item_map_))) {
LOG_WARN("failed to assign select item map", K(ret));
} else if (QueryRelation::QUERY_UNCOMPARABLE != relation) {
if (map_info.is_select_item_equal_ && QueryRelation::QUERY_EQUAL == relation) {
if (ref_query_map_info.is_select_item_equal_ && QueryRelation::QUERY_EQUAL == relation) {
map_info.table_map_.at(first_table_index - 1) = second_table_index - 1;
if (OB_FAIL(append(map_info.equal_param_map_, ref_query_map_info.equal_param_map_))) {
LOG_WARN("failed to append equal param", K(ret));
@ -1189,6 +1259,7 @@ int ObStmtComparer::compare_set_stmt(const ObSelectStmt *first,
}
}
if (OB_SUCC(ret) && QueryRelation::QUERY_EQUAL == set_query_relation) {
map_info.is_select_item_equal_ = true;
for (int64_t i = 0; OB_SUCC(ret) && QueryRelation::QUERY_EQUAL == set_query_relation
&& i < map_info.view_select_item_map_.count(); ++i) {
const ObIArray<int64_t> &select_item_map = map_info.view_select_item_map_.at(i);
@ -1198,12 +1269,14 @@ int ObStmtComparer::compare_set_stmt(const ObSelectStmt *first,
}
} else if (map_info.select_item_map_.count() != select_item_map.count()) {
set_query_relation = QueryRelation::QUERY_UNCOMPARABLE;
map_info.is_select_item_equal_ = false;
} else {
for (int64_t j = 0; OB_SUCC(ret) && QueryRelation::QUERY_EQUAL == set_query_relation &&
j < map_info.select_item_map_.count(); ++j) {
if (map_info.select_item_map_.at(j) != select_item_map.at(j) ||
OB_INVALID_ID == map_info.select_item_map_.at(j)) {
set_query_relation = QueryRelation::QUERY_UNCOMPARABLE;
map_info.is_select_item_equal_ = false;
}
}
}
@ -1224,6 +1297,49 @@ int ObStmtComparer::compare_set_stmt(const ObSelectStmt *first,
relation = QueryRelation::QUERY_LEFT_SUBSET;
}
}
// check order by exprs
if (OB_SUCC(ret) && QueryRelation::QUERY_UNCOMPARABLE != relation) {
int64_t first_count = first->get_order_item_size();
int64_t second_count = second->get_order_item_size();
int64_t match_count = 0;
if (0 == first_count && 0 == second_count) {
map_info.is_order_equal_ = true;
} else if (OB_FAIL(compute_orderby_map(first,
second,
first->get_order_items(),
second->get_order_items(),
map_info,
map_info.order_map_,
match_count))) {
LOG_WARN("failed to compute order item map", K(ret));
} else if (match_count == first_count && match_count == second_count) {
map_info.is_order_equal_ = true;
LOG_TRACE("succeed to check order item map", K(relation), K(map_info));
} else {
// The Order Item relation does not afftect the query relation
LOG_TRACE("succeed to check order item map", K(relation), K(map_info));
}
}
// check limit exprs
if (OB_SUCC(ret) && QueryRelation::QUERY_UNCOMPARABLE != relation) {
if (!first->has_limit() && !second->has_limit()) {
LOG_TRACE("succeed to check limit expr", K(relation), K(map_info));
} else if (first->has_limit() && !second->has_limit() &&
(relation == QueryRelation::QUERY_LEFT_SUBSET ||
relation == QueryRelation::QUERY_EQUAL)) {
relation = QueryRelation::QUERY_LEFT_SUBSET;
LOG_TRACE("succeed to check limit expr", K(relation), K(map_info));
} else if (!first->has_limit() && second->has_limit() &&
(relation == QueryRelation::QUERY_RIGHT_SUBSET ||
relation == QueryRelation::QUERY_EQUAL)) {
relation = QueryRelation::QUERY_RIGHT_SUBSET;
LOG_TRACE("succeed to check limit expr", K(relation), K(map_info));
} else {
relation = QueryRelation::QUERY_UNCOMPARABLE;
LOG_TRACE("succeed to check limit expr", K(relation), K(map_info));
}
}
}
return ret;
}

View File

@ -43,6 +43,7 @@ enum QueryRelation
common::ObSEArray<int64_t, 4> cond_map_;
common::ObSEArray<int64_t, 4> group_map_;
common::ObSEArray<int64_t, 4> having_map_;
common::ObSEArray<int64_t, 4> order_map_;
common::ObSEArray<int64_t, 4> select_item_map_;
bool is_table_equal_;
bool is_from_equal_;
@ -50,6 +51,7 @@ enum QueryRelation
bool is_cond_equal_;
bool is_group_equal_;
bool is_having_equal_;
bool is_order_equal_;
bool is_select_item_equal_;
bool is_distinct_equal_;
@ -62,6 +64,7 @@ enum QueryRelation
is_cond_equal_(false),
is_group_equal_(false),
is_having_equal_(false),
is_order_equal_(false),
is_select_item_equal_(false),
is_distinct_equal_(false)
{}
@ -228,6 +231,14 @@ public:
ObIArray<int64_t> &condition_map,
int64_t &match_count);
static int compute_orderby_map(const ObDMLStmt *first,
const ObDMLStmt *second,
const ObIArray<OrderItem> &first_orders,
const ObIArray<OrderItem> &second_orders,
ObStmtMapInfo &map_info,
ObIArray<int64_t> &order_map,
int64_t &match_count);
static int compute_from_items_map(const ObDMLStmt *first,
const ObDMLStmt *second,
ObStmtMapInfo &map_info,

View File

@ -612,7 +612,7 @@ bool ObTransformTempTable::is_similar_stmt(ObSelectStmt& stmt,
{
bool bret = false;
if (stmt.is_set_stmt()) {
bret = QueryRelation::QUERY_EQUAL == relation;
bret = QueryRelation::QUERY_EQUAL == relation && map_info.is_order_equal_;;
} else if (stmt.get_table_size() < 2) {
if (stmt.get_group_expr_size() > 0 ||
stmt.get_rollup_expr_size() > 0) {