diff --git a/src/sql/optimizer/ob_explain_note.h b/src/sql/optimizer/ob_explain_note.h index 6cd0c8c656..9362e514dd 100644 --- a/src/sql/optimizer/ob_explain_note.h +++ b/src/sql/optimizer/ob_explain_note.h @@ -35,6 +35,7 @@ namespace sql #define PARALLEL_DISABLED_BY_PL_UDF_DAS "Degree of Parallelisim is %ld because stmt contain pl_udf which force das scan" #define DIRECT_MODE_INSERT_INTO_SELECT "Direct-mode is enabled in insert into select" #define PARALLEL_DISABLED_BY_DBLINK "Degree of Parallelisim is %ld because stmt contain dblink which force das scan" +#define PDML_DISABLED_BY_INSERT_PK_AUTO_INC "PDML disabled because the insert statement primary key has specified auto-increment column" } } diff --git a/src/sql/optimizer/ob_insert_log_plan.cpp b/src/sql/optimizer/ob_insert_log_plan.cpp index b738183536..1c13cf889b 100644 --- a/src/sql/optimizer/ob_insert_log_plan.cpp +++ b/src/sql/optimizer/ob_insert_log_plan.cpp @@ -325,6 +325,8 @@ int ObInsertLogPlan::check_need_online_stats_gather(bool &need_osg) ObObj online_sys_var_obj; const ObInsertStmt *insert_stmt = NULL; TableItem *ins_table = NULL; + bool disable_pdml = false; + bool is_pk_auto_inc = false; if (OB_ISNULL(insert_stmt = get_stmt()) || OB_ISNULL(ins_table = insert_stmt->get_table_item_by_id(insert_stmt->get_insert_table_info().table_id_))) { ret = OB_ERR_UNEXPECTED; @@ -334,6 +336,11 @@ int ObInsertLogPlan::check_need_online_stats_gather(bool &need_osg) || !insert_stmt->value_from_select() || (!get_optimizer_context().get_session_info()->is_user_session())) { need_gathering = false; + } else if (OB_FAIL(insert_stmt->check_pdml_disabled(get_optimizer_context().is_online_ddl(), + disable_pdml, is_pk_auto_inc))) { + LOG_WARN("fail to check pdml disable for insert stmt", K(ret)); + } else if (disable_pdml) { + need_gathering = false; } if (OB_FAIL(ret)) { diff --git a/src/sql/optimizer/ob_optimizer.cpp b/src/sql/optimizer/ob_optimizer.cpp index c631227688..445f1bfc14 100644 --- a/src/sql/optimizer/ob_optimizer.cpp +++ b/src/sql/optimizer/ob_optimizer.cpp @@ -332,6 +332,8 @@ int ObOptimizer::check_pdml_enabled(const ObDMLStmt &stmt, bool session_enable_pdml = false; bool enable_auto_dop = false; uint64_t session_pdml_dop = ObGlobalHint::UNSET_PARALLEL; + bool disable_pdml = false; + bool is_pk_auto_inc = false; if (OB_ISNULL(ctx_.get_exec_ctx()) || OB_ISNULL(query_ctx = ctx_.get_query_ctx())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null", K(ret), K(ctx_.get_exec_ctx()), K(query_ctx)); @@ -348,8 +350,15 @@ int ObOptimizer::check_pdml_enabled(const ObDMLStmt &stmt, } else if (ctx_.has_var_assign() && !ctx_.is_var_assign_only_in_root_stmt()) { can_use_pdml = false; } else if (stmt::T_INSERT == stmt.get_stmt_type() && - !static_cast< const ObInsertStmt &>(stmt).value_from_select()) { + OB_FAIL(static_cast< const ObInsertStmt &>(stmt).check_pdml_disabled(ctx_.is_online_ddl(), + disable_pdml, + is_pk_auto_inc))) { + LOG_WARN("fail to check pdml disabled for insert stmt", K(ret)); + } else if (disable_pdml) { can_use_pdml = false; + if (is_pk_auto_inc) { + ctx_.add_plan_note(PDML_DISABLED_BY_INSERT_PK_AUTO_INC); + } } else if ((stmt.is_update_stmt() || stmt.is_delete_stmt()) && static_cast(stmt).dml_source_from_join() && static_cast(stmt).is_dml_table_from_join()) { diff --git a/src/sql/resolver/dml/ob_insert_stmt.cpp b/src/sql/resolver/dml/ob_insert_stmt.cpp index f929a750eb..fc08d5566a 100644 --- a/src/sql/resolver/dml/ob_insert_stmt.cpp +++ b/src/sql/resolver/dml/ob_insert_stmt.cpp @@ -448,5 +448,65 @@ int64_t ObInsertStmt::get_instead_of_trigger_column_count() const return column_count; } +int ObInsertStmt::check_pdml_disabled(const bool is_online_ddl, + bool &disable_pdml, bool &is_pk_auto_inc) const +{ + int ret = OB_SUCCESS; + disable_pdml = false; + is_pk_auto_inc = false; + if (!value_from_select()) { + disable_pdml = true; + } else if (is_online_ddl) { + disable_pdml = false; // keep online ddl use pdml + } else { + const common::ObIArray &column_conv_exprs = get_column_conv_exprs(); + const common::ObIArray &column_exprs = table_info_.column_exprs_; + if (OB_UNLIKELY(column_exprs.count() != column_conv_exprs.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected column count", K(ret), + K(column_exprs.count()), K(column_conv_exprs.count())); + } else { + for (int64_t i = 0; OB_SUCC(ret) && !disable_pdml && i < column_conv_exprs.count(); ++i) { + const ObColumnRefRawExpr *column_expr = column_exprs.at(i); + const ObRawExpr *column_conv_expr = column_conv_exprs.at(i); + if (OB_ISNULL(column_expr) || OB_ISNULL(column_conv_expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null expr", K(ret)); + } else if (column_expr->is_rowkey_column() || column_expr->is_table_part_key_column()) { + const ObRawExpr *auto_inc_expr = NULL; + if (OB_FAIL(find_first_auto_inc_expr(column_conv_expr, auto_inc_expr))) { + LOG_WARN("fail to find first auto inc expr", K(ret)); + } else if (auto_inc_expr != NULL) { + disable_pdml = auto_inc_expr->get_param_count() > 0; // means the specified value exists + } + } + } + if (OB_SUCC(ret) && disable_pdml) { + is_pk_auto_inc = true; + } + } + } + LOG_TRACE("check insert pdml disabled", K(is_online_ddl), K(disable_pdml), K(is_pk_auto_inc)); + return ret; +} + +int ObInsertStmt::find_first_auto_inc_expr(const ObRawExpr *expr, const ObRawExpr *&auto_inc) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr is null", K(ret)); + } else if (T_FUN_SYS_AUTOINC_NEXTVAL == expr->get_expr_type()) { + auto_inc = expr; + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < expr->get_param_count(); ++i) { + if (OB_FAIL(find_first_auto_inc_expr(expr->get_param_expr(i), auto_inc))) { + LOG_WARN("fail to find first auto inc expr", K(ret), K(i), K(expr)); + } + } + } + return ret; +} + } // namespace sql } // namespace oceanbase diff --git a/src/sql/resolver/dml/ob_insert_stmt.h b/src/sql/resolver/dml/ob_insert_stmt.h index aa788359e6..0c70d189ce 100644 --- a/src/sql/resolver/dml/ob_insert_stmt.h +++ b/src/sql/resolver/dml/ob_insert_stmt.h @@ -73,6 +73,8 @@ public: int part_key_has_subquery(bool &has) const ; int part_key_has_auto_inc(bool &has) const; int part_key_is_updated(bool &is_updated) const; + int check_pdml_disabled(const bool is_online_ddl, bool &disable_pdml, bool &is_pk_auto_inc) const; + int find_first_auto_inc_expr(const ObRawExpr *expr, const ObRawExpr *&auto_inc) const; virtual int get_value_exprs(ObIArray &value_exprs) const override; // use this only when part_generated_col_dep_cols_.count() is not zero int get_values_desc_for_heap_table(common::ObIArray &arr) const;