diff --git a/src/sql/rewrite/ob_stmt_comparer.cpp b/src/sql/rewrite/ob_stmt_comparer.cpp index 8c51c6043..2007dfb73 100644 --- a/src/sql/rewrite/ob_stmt_comparer.cpp +++ b/src/sql/rewrite/ob_stmt_comparer.cpp @@ -1384,18 +1384,15 @@ int ObStmtComparer::compute_tables_map(const ObDMLStmt *first, } -int ObStmtComparer::compare_basic_table_item(const ObDMLStmt *first, - const TableItem *first_table, - const ObDMLStmt *second, - const TableItem *second_table, - QueryRelation &relation) +int ObStmtComparer::compare_basic_table_item(const TableItem *first_table, + const TableItem *second_table, + QueryRelation &relation) { int ret = OB_SUCCESS; relation = QueryRelation::QUERY_UNCOMPARABLE; - if (OB_ISNULL(first) || OB_ISNULL(first_table) - || OB_ISNULL(second) || OB_ISNULL(second_table)) { + if (OB_ISNULL(first_table) || OB_ISNULL(second_table)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("param has null", K(first), K(first_table), K(second), K(second_table)); + LOG_WARN("param has null", K(first_table), K(second_table)); } else if ((first_table->is_basic_table() || first_table->is_link_table()) && (second_table->is_basic_table() || second_table->is_link_table()) && first_table->ref_id_ == second_table->ref_id_ @@ -1568,11 +1565,9 @@ int ObStmtComparer::compare_table_item(const ObDMLStmt *first, } } else if ((first_table->is_basic_table() || first_table->is_link_table()) && (second_table->is_basic_table() || second_table->is_link_table())) { - if (OB_FAIL(compare_basic_table_item(first, - first_table, - second, - second_table, - relation))) { + if (OB_FAIL(compare_basic_table_item(first_table, + second_table, + relation))) { LOG_WARN("compare table part failed",K(ret), K(first_table), K(second_table)); } else if (QueryRelation::QUERY_UNCOMPARABLE != relation) { const int32_t first_table_index = first->get_table_bit_index(first_table->table_id_); diff --git a/src/sql/rewrite/ob_stmt_comparer.h b/src/sql/rewrite/ob_stmt_comparer.h index a219947c9..0636026d9 100644 --- a/src/sql/rewrite/ob_stmt_comparer.h +++ b/src/sql/rewrite/ob_stmt_comparer.h @@ -338,11 +338,9 @@ public: * 如果两张表相同且没有partition hint,则相等 * 如果两张表都是generated_table只比较引用的子查询是否相同 */ - static int compare_basic_table_item (const ObDMLStmt *first, - const TableItem *first_table, - const ObDMLStmt *second, - const TableItem *second_table, - QueryRelation &relation); + static int compare_basic_table_item (const TableItem *first_table, + const TableItem *second_table, + QueryRelation &relation); /** * @brief compare_joined_table_item diff --git a/src/sql/rewrite/ob_transform_mv_rewrite.cpp b/src/sql/rewrite/ob_transform_mv_rewrite.cpp index 46d2879f4..63400a461 100644 --- a/src/sql/rewrite/ob_transform_mv_rewrite.cpp +++ b/src/sql/rewrite/ob_transform_mv_rewrite.cpp @@ -257,7 +257,7 @@ int ObTransformMVRewrite::gen_base_table_map(const ObIArray &from_ta if (OB_ISNULL(from_table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null table", K(ret), K(i)); - } else if (!(from_table->is_basic_table() || from_table->is_generated_table()) + } else if (!(from_table->is_basic_table() || from_table->is_link_table()) || OB_INVALID_ID == from_table->ref_id_) { // do nothing } else if (NULL == (num = from_table_num.get(from_table->ref_id_))) { @@ -275,7 +275,7 @@ int ObTransformMVRewrite::gen_base_table_map(const ObIArray &from_ta if (OB_ISNULL(to_table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null table", K(ret), K(i)); - } else if (!(to_table->is_basic_table() || to_table->is_generated_table()) + } else if (!(to_table->is_basic_table() || to_table->is_link_table()) || OB_INVALID_ID == to_table->ref_id_) { // do nothing } else if (NULL == (idx = to_table_map.get(to_table->ref_id_))) { @@ -301,6 +301,7 @@ int ObTransformMVRewrite::gen_base_table_map(const ObIArray &from_ta LOG_WARN("failed to prepare allocate map array", K(ret), K(from_tables.count())); } else if (OB_FAIL(inner_gen_base_table_map(0, from_tables, + to_tables, from_table_num, to_table_ids, to_table_map, @@ -321,6 +322,7 @@ int ObTransformMVRewrite::gen_base_table_map(const ObIArray &from_ta // generate a base table map for from_table_idx-th from table int ObTransformMVRewrite::inner_gen_base_table_map(int64_t from_table_idx, const ObIArray &from_tables, + const ObIArray &to_tables, hash::ObHashMap &from_table_num, const ObIArray> &to_table_ids, const hash::ObHashMap &to_table_map, @@ -352,13 +354,14 @@ int ObTransformMVRewrite::inner_gen_base_table_map(int64_t from_table_idx, if (OB_ISNULL(from_table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("from table item is NULL", K(ret), K(from_table_idx)); - } else if (!(from_table->is_basic_table() || from_table->is_generated_table()) + } else if (!(from_table->is_basic_table() || from_table->is_link_table()) || OB_INVALID_ID == from_table->ref_id_ || NULL == (to_idx = to_table_map.get(from_table->ref_id_))) { - // table does not exists in to_tables + // table does not exists in to_tables, map from_table to nothing current_map.at(from_table_idx) = -1; if (OB_FAIL(SMART_CALL(inner_gen_base_table_map(from_table_idx + 1, from_tables, + to_tables, from_table_num, to_table_ids, to_table_map, @@ -372,17 +375,27 @@ int ObTransformMVRewrite::inner_gen_base_table_map(int64_t from_table_idx, ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected to_idx", K(ret), K(*to_idx)); } else { + bool has_mapped = false; // try to map from_table to to_table which has same ref_id and not be used for (int64_t i = 0; OB_SUCC(ret) && max_map_num > table_maps.count() && i < to_table_ids.at(*to_idx).count(); ++i) { int64_t to_table_idx = to_table_ids.at(*to_idx).at(i); + QueryRelation relation = QueryRelation::QUERY_UNCOMPARABLE; if (used_to_table.has_member(to_table_idx)) { // do nothing, to_table has been used + } else if (OB_FAIL(ObStmtComparer::compare_basic_table_item(from_tables.at(from_table_idx), + to_tables.at(to_table_idx), + relation))) { + LOG_WARN("failed to compare basic table", K(ret), K(from_table_idx), K(to_table_idx)); + } else if (QueryRelation::QUERY_EQUAL != relation) { + // do nothing, from table and to table are not equal + } else if (OB_FALSE_IT(has_mapped = true)) { } else if (OB_FAIL(used_to_table.add_member(to_table_idx))) { LOG_WARN("failed to add member", K(ret)); } else if (OB_FALSE_IT(current_map.at(from_table_idx) = to_table_idx)) { } else if (OB_FAIL(SMART_CALL(inner_gen_base_table_map(from_table_idx + 1, from_tables, + to_tables, from_table_num, to_table_ids, to_table_map, @@ -397,20 +410,19 @@ int ObTransformMVRewrite::inner_gen_base_table_map(int64_t from_table_idx, } // try to map from_table to nothing int64_t from_num; // number of from tables with the same ref_id minus table has been mapped to -1 - if (OB_FAIL(ret) || max_map_num <= table_maps.count() - || !(from_table->is_basic_table() || from_table->is_generated_table()) - || OB_INVALID_ID == from_table->ref_id_) { + if (OB_FAIL(ret) || max_map_num <= table_maps.count()) { // do nothing } else if (OB_FAIL(from_table_num.get_refactored(from_table->ref_id_, from_num))) { LOG_WARN("failed to get from table num", K(ret), KPC(from_table)); - } else if (from_num <= to_table_ids.at(*to_idx).count()) { + } else if (has_mapped && from_num <= to_table_ids.at(*to_idx).count()) { // do nothing, the number of remaining unmapped from tables is less than or equal to - // the number of remaining to tables, can not map from_table to nothing. + // the number of remaining to tables, should not map from_table to nothing. } else if (OB_FAIL(from_table_num.set_refactored(from_table->ref_id_, from_num - 1, 1))) { LOG_WARN("failed to set from table num", K(ret), KPC(from_table)); } else if (OB_FALSE_IT(current_map.at(from_table_idx) = -1)) { } else if (OB_FAIL(SMART_CALL(inner_gen_base_table_map(from_table_idx + 1, from_tables, + to_tables, from_table_num, to_table_ids, to_table_map, diff --git a/src/sql/rewrite/ob_transform_mv_rewrite.h b/src/sql/rewrite/ob_transform_mv_rewrite.h index 9723c955d..b97f5939a 100644 --- a/src/sql/rewrite/ob_transform_mv_rewrite.h +++ b/src/sql/rewrite/ob_transform_mv_rewrite.h @@ -200,6 +200,7 @@ private: ObIArray> &table_maps); int inner_gen_base_table_map(int64_t from_rel_id, const ObIArray &from_tables, + const ObIArray &to_tables, hash::ObHashMap &from_table_num, const ObIArray> &to_table_ids, const hash::ObHashMap &to_table_map, diff --git a/src/sql/rewrite/ob_transform_utils.cpp b/src/sql/rewrite/ob_transform_utils.cpp index b7dcfb24d..c507d971e 100644 --- a/src/sql/rewrite/ob_transform_utils.cpp +++ b/src/sql/rewrite/ob_transform_utils.cpp @@ -6272,11 +6272,9 @@ int ObTransformUtils::check_table_item_containment(ObDMLStmt *source_stmt, } else if (source_table->is_basic_table() && target_table->is_basic_table()) { QueryRelation relation = QueryRelation::QUERY_UNCOMPARABLE; //zhenling.zzg 修复存在partition hint的情况下,正确性bug - if (OB_FAIL(ObStmtComparer::compare_basic_table_item(source_stmt, - source_table, - target_stmt, - target_table, - relation))) { + if (OB_FAIL(ObStmtComparer::compare_basic_table_item(source_table, + target_table, + relation))) { LOG_WARN("compare table part failed",K(ret), K(source_table), K(target_table)); } else if (QueryRelation::QUERY_LEFT_SUBSET == relation || QueryRelation::QUERY_EQUAL == relation) {