From 49a8d8bb2b5aa5eb37ada9ce639c7946006fc640 Mon Sep 17 00:00:00 2001 From: ChangerR Date: Fri, 16 Jun 2023 03:42:31 +0000 Subject: [PATCH] fix some bugs --- src/share/schema/ob_schema_getter_guard.cpp | 15 ++-- src/share/schema/ob_schema_getter_guard.h | 7 +- src/sql/optimizer/ob_explain_note.h | 1 + src/sql/optimizer/ob_join_order.cpp | 5 +- src/sql/optimizer/ob_log_set.cpp | 5 +- src/sql/optimizer/ob_log_subplan_filter.cpp | 6 +- src/sql/optimizer/ob_optimizer.cpp | 78 +++++++++++++++++++-- src/sql/optimizer/ob_optimizer.h | 4 ++ src/sql/optimizer/ob_optimizer_util.cpp | 18 +++-- src/sql/optimizer/ob_optimizer_util.h | 6 +- 10 files changed, 112 insertions(+), 33 deletions(-) diff --git a/src/share/schema/ob_schema_getter_guard.cpp b/src/share/schema/ob_schema_getter_guard.cpp index 3f359a0723..8abddb415c 100644 --- a/src/share/schema/ob_schema_getter_guard.cpp +++ b/src/share/schema/ob_schema_getter_guard.cpp @@ -329,16 +329,14 @@ int ObSchemaGetterGuard::check_has_local_unique_index( return ret; } -int ObSchemaGetterGuard::check_has_global_unique_index( - const uint64_t tenant_id, - const uint64_t table_id, - bool &has_global_unique_index) +int ObSchemaGetterGuard::get_all_unique_index(const uint64_t tenant_id, + const uint64_t table_id, + ObIArray &unique_index_ids) { int ret = OB_SUCCESS; const ObTableSchema *table_schema = NULL; ObSEArray simple_index_infos; const ObSimpleTableSchemaV2 *index_schema = NULL; - has_global_unique_index = false; if (OB_FAIL(get_table_schema(tenant_id, table_id, table_schema))) { LOG_WARN("failed to get table schema", KR(ret), K(tenant_id), K(table_id)); } else if (OB_ISNULL(table_schema)) { @@ -357,9 +355,10 @@ int ObSchemaGetterGuard::check_has_global_unique_index( KR(ret), K(tenant_id), K(index_id)); } else if (OB_UNLIKELY(index_schema->is_final_invalid_index())) { //invalid index status, need ingore - } else if (index_schema->is_global_unique_index_table()) { - has_global_unique_index = true; - break; + } else if ((index_schema->is_local_unique_index_table() || + index_schema->is_global_unique_index_table()) && + OB_FAIL(unique_index_ids.push_back(index_id))) { + LOG_WARN("failed to push back local unique index", K(ret)); } } return ret; diff --git a/src/share/schema/ob_schema_getter_guard.h b/src/share/schema/ob_schema_getter_guard.h index 76872cc8b5..e1342f248d 100644 --- a/src/share/schema/ob_schema_getter_guard.h +++ b/src/share/schema/ob_schema_getter_guard.h @@ -182,10 +182,9 @@ public: const uint64_t tenant_id, const uint64_t table_id, bool &has_local_unique_index); - int check_has_global_unique_index( - const uint64_t tenant_id, - const uint64_t table_id, - bool &has_global_unique_index); + int get_all_unique_index(const uint64_t tenant_id, + const uint64_t table_id, + ObIArray &unique_index_ids); bool is_tenant_schema_valid(const int64_t tenant_id) const; /* interface for simple schema diff --git a/src/sql/optimizer/ob_explain_note.h b/src/sql/optimizer/ob_explain_note.h index 2af70b5e99..6cd0c8c656 100644 --- a/src/sql/optimizer/ob_explain_note.h +++ b/src/sql/optimizer/ob_explain_note.h @@ -24,6 +24,7 @@ namespace sql #define PDML_DISABLED_BY_NESTED_SQL "PDML disabled because the modified table has foreign key/trigger/user defined function" #define PDML_DISABLED_BY_LOCAL_UK "PDML disabled because the modified table has local unique index" #define PDML_DISABLED_BY_GLOBAL_UK "PDML disabled because the modified table has global unique index in merge into statement" +#define PDML_DISABLE_BY_MERGE_UPDATE_PK "PDML disabled because the merge statement update primary key or unique index key" #define PDML_DISABLED_BY_IGNORE "PDML disabled because it is an dml ignore query" #define PDML_DISABLED_BY_UPDATE_NOW "PDML disabled by update now" #define PARALLEL_ENABLED_BY_GLOBAL_HINT "Degree of Parallelism is %ld because of hint" diff --git a/src/sql/optimizer/ob_join_order.cpp b/src/sql/optimizer/ob_join_order.cpp index 58e92dea62..1b59b8346b 100644 --- a/src/sql/optimizer/ob_join_order.cpp +++ b/src/sql/optimizer/ob_join_order.cpp @@ -5056,10 +5056,9 @@ int JoinPath::compute_join_path_sharding() input_shardings, *parent_->get_allocator(), reselected_dup_pos, - strong_sharding_))) { + strong_sharding_, + inherit_sharding_index_))) { LOG_WARN("failed to compute basic sharding info", K(ret)); - } else if (OB_FALSE_IT(inherit_sharding_index_ = 0)) { - //do nothing } else if (reselected_dup_pos.empty()) { /*no duplicated table, do nothing*/ } else if (OB_UNLIKELY(2 != reselected_dup_pos.count())) { diff --git a/src/sql/optimizer/ob_log_set.cpp b/src/sql/optimizer/ob_log_set.cpp index aa41a45613..151858379e 100644 --- a/src/sql/optimizer/ob_log_set.cpp +++ b/src/sql/optimizer/ob_log_set.cpp @@ -304,10 +304,9 @@ int ObLogSet::compute_sharding_info() get_child_list(), get_plan()->get_allocator(), dup_table_pos_, - strong_sharding_))) { + strong_sharding_, + inherit_sharding_index_))) { LOG_WARN("failed to compute basic sharding info", K(ret)); - } else { - inherit_sharding_index_ = 0; } } else if (DistAlgo::DIST_PULL_TO_LOCAL == set_dist_algo_) { strong_sharding_ = get_plan()->get_optimizer_context().get_local_sharding(); diff --git a/src/sql/optimizer/ob_log_subplan_filter.cpp b/src/sql/optimizer/ob_log_subplan_filter.cpp index bb44bd7533..72209808b3 100644 --- a/src/sql/optimizer/ob_log_subplan_filter.cpp +++ b/src/sql/optimizer/ob_log_subplan_filter.cpp @@ -377,15 +377,17 @@ int ObLogSubPlanFilter::compute_sharding_info() ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(get_plan()), K(ret)); } else if (DistAlgo::DIST_BASIC_METHOD == dist_algo_) { + ObShardingInfo *sharding = NULL; if (OB_FAIL(ObOptimizerUtil::compute_basic_sharding_info( get_plan()->get_optimizer_context().get_local_server_addr(), get_child_list(), get_plan()->get_allocator(), dup_table_pos_, - strong_sharding_))) { + strong_sharding_, + inherit_sharding_index_))) { LOG_WARN("failed to compute basic sharding info", K(ret)); } else { - inherit_sharding_index_ = ObLogicalOperator::first_child; + strong_sharding_->set_can_reselect_replica(false); } } else if (DistAlgo::DIST_PULL_TO_LOCAL == dist_algo_) { strong_sharding_ = get_plan()->get_optimizer_context().get_local_sharding(); diff --git a/src/sql/optimizer/ob_optimizer.cpp b/src/sql/optimizer/ob_optimizer.cpp index 4daff5628c..ba58a6dd08 100644 --- a/src/sql/optimizer/ob_optimizer.cpp +++ b/src/sql/optimizer/ob_optimizer.cpp @@ -24,6 +24,7 @@ #include "sql/ob_optimizer_trace_impl.h" #include "sql/engine/cmd/ob_table_direct_insert_service.h" #include "sql/dblink/ob_dblink_utils.h" +#include "sql/resolver/dml/ob_merge_stmt.h" using namespace oceanbase; using namespace sql; using namespace oceanbase::common; @@ -445,14 +446,22 @@ int ObOptimizer::check_pdml_supported_feature(const ObDelUpdStmt &pdml_stmt, } } } else if (stmt::T_MERGE == pdml_stmt.get_stmt_type()) { - bool with_unique_global_idx = false; - if (OB_FAIL(schema_guard->check_has_global_unique_index( - session.get_effective_tenant_id(), - main_table_tid, with_unique_global_idx))) { - LOG_WARN("fail check if table with global unqiue index", K(main_table_tid), K(ret)); - } else if (with_unique_global_idx) { + bool update_rowkey = false; + ObSEArray index_ids; + if (OB_FAIL(schema_guard->get_all_unique_index(session.get_effective_tenant_id(), + main_table_tid, + index_ids))) { + LOG_WARN("failed to get all local unique index", K(ret)); + } else if (OB_FAIL(index_ids.push_back(main_table_tid))) { + LOG_WARN("failed to push back index ids", K(ret)); + } else if (OB_FAIL(check_merge_stmt_is_update_index_rowkey(session, + pdml_stmt, + index_ids, + update_rowkey))) { + LOG_WARN("failed to check merge stmt update rowkey", K(ret)); + } else if (update_rowkey) { is_use_pdml = false; - ctx_.add_plan_note(PDML_DISABLED_BY_GLOBAL_UK); + ctx_.add_plan_note(PDML_DISABLE_BY_MERGE_UPDATE_PK); } } } @@ -974,5 +983,60 @@ int ObOptimizer::check_force_default_stat() } else if (is_exists_opt && use_default_opt_stat) { ctx_.set_use_default_stat(); } + return ret; +} + +int ObOptimizer::check_merge_stmt_is_update_index_rowkey(const ObSQLSessionInfo &session, + const ObDMLStmt &stmt, + const ObIArray &index_ids, + bool &is_update) +{ + int ret = OB_SUCCESS; + share::schema::ObSchemaGetterGuard *schema_guard = ctx_.get_schema_guard(); + const ObTableSchema *table_schema = NULL; + const ObMergeStmt &merge_stmt = static_cast(stmt); + const ObMergeTableInfo& merge_table_info = merge_stmt.get_merge_table_info(); + ObSEArray rowkey_ids; + ObSEArray tmp_rowkey_ids; + const ObColumnRefRawExpr* column_expr = nullptr; + const ColumnItem* column_item = nullptr; + is_update = false; + if (OB_ISNULL(schema_guard) || + OB_UNLIKELY(stmt::T_MERGE != stmt.get_stmt_type())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the schema guard is null", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < index_ids.count(); ++i) { + tmp_rowkey_ids.reuse(); + if (OB_FAIL(schema_guard->get_table_schema(session.get_effective_tenant_id(), + index_ids.at(i), + table_schema))) { + LOG_WARN("failed to get table schema", K(ret)); + } else if (OB_ISNULL(table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpect null", K(ret), K(table_schema)); + } else if (OB_FAIL(table_schema->get_rowkey_info().get_column_ids(tmp_rowkey_ids))) { + LOG_WARN("failed to get column ids", K(ret)); + } else if (OB_FAIL(append_array_no_dup(rowkey_ids, tmp_rowkey_ids))) { + LOG_WARN("failed to append array no dup", K(ret)); + } + } + for (int64_t i = 0; OB_SUCC(ret) && !is_update && i < merge_table_info.assignments_.count(); ++i) { + if (OB_ISNULL(column_expr = merge_table_info.assignments_.at(i).column_expr_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get null column expr", K(ret)); + } else if (merge_table_info.table_id_ != merge_table_info.loc_table_id_) { + if (OB_ISNULL(column_item = stmt.get_column_item_by_id(column_expr->get_table_id(), + column_expr->get_column_id()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get null column item", K(ret)); + } else { + is_update = ObOptimizerUtil::find_item(rowkey_ids, column_item->base_cid_); + } + } else { + is_update = ObOptimizerUtil::find_item(rowkey_ids, column_expr->get_column_id()); + } + } + return ret; } \ No newline at end of file diff --git a/src/sql/optimizer/ob_optimizer.h b/src/sql/optimizer/ob_optimizer.h index 732173d213..70d89c4d7b 100644 --- a/src/sql/optimizer/ob_optimizer.h +++ b/src/sql/optimizer/ob_optimizer.h @@ -205,6 +205,10 @@ namespace sql const ObSQLSessionInfo &session, bool &is_use_pdml); int check_is_heap_table(const ObDMLStmt &stmt); + int check_merge_stmt_is_update_index_rowkey(const ObSQLSessionInfo &session, + const ObDMLStmt &stmt, + const ObIArray &index_ids, + bool &is_update); int extract_column_usage_info(const ObDMLStmt &stmt); int analyze_one_expr(const ObDMLStmt &stmt, const ObRawExpr *expr); int add_column_usage_arg(const ObDMLStmt &stmt, diff --git a/src/sql/optimizer/ob_optimizer_util.cpp b/src/sql/optimizer/ob_optimizer_util.cpp index b584916861..1df532d969 100644 --- a/src/sql/optimizer/ob_optimizer_util.cpp +++ b/src/sql/optimizer/ob_optimizer_util.cpp @@ -7284,7 +7284,8 @@ int ObOptimizerUtil::compute_basic_sharding_info(const ObAddr &local_addr, const ObIArray &child_ops, ObIAllocator &allocator, ObIArray &reselected_pos, - ObShardingInfo *&result_sharding) + ObShardingInfo *&result_sharding, + int64_t &inherit_sharding_index) { int ret = OB_SUCCESS; ObSEArray sharding_infos; @@ -7304,7 +7305,8 @@ int ObOptimizerUtil::compute_basic_sharding_info(const ObAddr &local_addr, sharding_infos, allocator, reselected_pos, - result_sharding))) { + result_sharding, + inherit_sharding_index))) { LOG_WARN("failed to compute basic sharding info", K(ret)); } else { /*do nothing*/ } return ret; @@ -7314,12 +7316,15 @@ int ObOptimizerUtil::compute_basic_sharding_info(const ObAddr &local_addr, const ObIArray &input_shardings, ObIAllocator &allocator, ObIArray &reselected_pos, - ObShardingInfo *&result_sharding) + ObShardingInfo *&result_sharding, + int64_t &inherit_sharding_index) { int ret = OB_SUCCESS; result_sharding = NULL; + inherit_sharding_index = 0; if (input_shardings.count() <= 1) { result_sharding = input_shardings.at(0); + inherit_sharding_index = 0; } else { ObAddr basic_addr; bool has_duplicated = false; @@ -7361,11 +7366,13 @@ int ObOptimizerUtil::compute_basic_sharding_info(const ObAddr &local_addr, } else if (sharding->is_local()) { basic_addr = local_addr; result_sharding = sharding; + inherit_sharding_index = i; } else if (sharding->is_remote()) { if (OB_FAIL(sharding->get_remote_addr(basic_addr))) { LOG_WARN("failed to get remote addr", K(ret)); } else { result_sharding = sharding; + inherit_sharding_index = i; } } else { /*do nothing*/ } } @@ -7382,6 +7389,7 @@ int ObOptimizerUtil::compute_basic_sharding_info(const ObAddr &local_addr, } } else { result_sharding = input_shardings.at(0); + inherit_sharding_index = 0; } } if (OB_FAIL(ret)) { @@ -7409,7 +7417,9 @@ int ObOptimizerUtil::compute_basic_sharding_info(const ObAddr &local_addr, can_reselect_replica, result_sharding))) { LOG_WARN("failed to compute duplicate table sharding", K(ret)); - } else { /*do nothing*/ } + } else if (NULL != result_sharding) { + inherit_sharding_index = i; + } } } } diff --git a/src/sql/optimizer/ob_optimizer_util.h b/src/sql/optimizer/ob_optimizer_util.h index ffc47e36dc..82d68184d8 100644 --- a/src/sql/optimizer/ob_optimizer_util.h +++ b/src/sql/optimizer/ob_optimizer_util.h @@ -1289,13 +1289,15 @@ public: const ObIArray &child_ops, ObIAllocator &allocator, ObIArray &reselected_pos, - ObShardingInfo *&result_sharding); + ObShardingInfo *&result_sharding, + int64_t &inherit_sharding_index); static int compute_basic_sharding_info(const ObAddr &local_addr, const ObIArray &input_shardings, ObIAllocator &allocator, ObIArray &reselected_pos, - ObShardingInfo *&result_sharding); + ObShardingInfo *&result_sharding, + int64_t &inherit_sharding_index); static int get_duplicate_table_replica(const ObCandiTableLoc &phy_table_loc, ObIArray &valid_addrs);