diff --git a/src/sql/engine/cmd/ob_table_direct_insert_service.cpp b/src/sql/engine/cmd/ob_table_direct_insert_service.cpp index 0a819b401..2fe310d75 100644 --- a/src/sql/engine/cmd/ob_table_direct_insert_service.cpp +++ b/src/sql/engine/cmd/ob_table_direct_insert_service.cpp @@ -10,6 +10,8 @@ #include "observer/table_load/ob_table_load_store.h" #include "sql/engine/ob_exec_context.h" #include "sql/engine/ob_physical_plan.h" +#include "sql/optimizer/ob_optimizer_context.h" +#include "sql/resolver/dml/ob_insert_stmt.h" namespace oceanbase { @@ -17,6 +19,36 @@ using namespace observer; namespace sql { +// Direct-insert is enabled only when: +// 1. _ob_enable_direct_load +// 2. insert into select clause +// 3. append hint + pdml +// 4. auto_commit, not in a transaction +int ObTableDirectInsertService::check_direct_insert(ObOptimizerContext &optimizer_ctx, + const ObDMLStmt &stmt, + bool &is_direct_insert) +{ + int ret = OB_SUCCESS; + bool auto_commit = false; + const ObSQLSessionInfo* session_info = optimizer_ctx.get_session_info(); + is_direct_insert = false; + if (OB_ISNULL(session_info)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", KR(ret), KP(session_info)); + } else if (OB_FAIL(session_info->get_autocommit(auto_commit))) { + LOG_WARN("failed to get auto commit", KR(ret)); + } else if (GCONF._ob_enable_direct_load + && stmt::T_INSERT == stmt.get_stmt_type() + && static_cast(stmt).value_from_select() + && optimizer_ctx.get_global_hint().has_append() + && optimizer_ctx.use_pdml() + && auto_commit + && (!session_info->is_in_transaction())){ + is_direct_insert = true; + } + return ret; +} + bool ObTableDirectInsertService::is_direct_insert(const ObPhysicalPlan &phy_plan) { return (phy_plan.get_enable_append() && (0 != phy_plan.get_append_table_id())); @@ -37,8 +69,7 @@ int ObTableDirectInsertService::start_direct_insert(ObExecContext &ctx, LOG_WARN("failed to get auto commit", KR(ret)); } else if (!auto_commit || session->is_in_transaction()) { ret = OB_NOT_SUPPORTED; - LOG_WARN("using direct-insert within a transaction is not supported", - KR(ret), K(auto_commit), K(session->is_in_transaction())); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "using direct-insert within a transaction is"); } else { ObTableDirectInsertCtx &table_direct_insert_ctx = ctx.get_table_direct_insert_ctx(); uint64_t table_id = phy_plan.get_append_table_id(); diff --git a/src/sql/engine/cmd/ob_table_direct_insert_service.h b/src/sql/engine/cmd/ob_table_direct_insert_service.h index f4a3ca8fe..2a7a461f3 100644 --- a/src/sql/engine/cmd/ob_table_direct_insert_service.h +++ b/src/sql/engine/cmd/ob_table_direct_insert_service.h @@ -12,10 +12,15 @@ namespace sql { class ObExecContext; class ObPhysicalPlan; +class ObOptimizerContext; +class ObDMLStmt; class ObTableDirectInsertService { public: + static int check_direct_insert(ObOptimizerContext &optimizer_ctx, + const ObDMLStmt &stmt, + bool &is_direct_insert); static bool is_direct_insert(const ObPhysicalPlan &phy_plan); // all insert-tasks within an insert into select clause are wrapped by a single direct insert instance static int start_direct_insert(ObExecContext &ctx, ObPhysicalPlan &plan); diff --git a/src/sql/optimizer/ob_del_upd_log_plan.cpp b/src/sql/optimizer/ob_del_upd_log_plan.cpp index 6c515d0fb..a41dfc911 100644 --- a/src/sql/optimizer/ob_del_upd_log_plan.cpp +++ b/src/sql/optimizer/ob_del_upd_log_plan.cpp @@ -21,6 +21,7 @@ #include "sql/resolver/dml/ob_merge_stmt.h" #include "sql/rewrite/ob_transform_utils.h" #include "sql/dblink/ob_dblink_utils.h" +#include "sql/engine/cmd/ob_table_direct_insert_service.h" using namespace oceanbase; using namespace sql; @@ -1532,8 +1533,10 @@ int ObDelUpdLogPlan::collect_related_local_index_ids(IndexDMLInfo &primary_dml_i if (OB_ISNULL(stmt) || OB_ISNULL(schema_guard = optimizer_context_.get_schema_guard())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("schema guard is nullptr", K(ret), K(stmt), K(schema_guard)); - } else if (OB_FAIL(is_direct_insert_into_select(is_direct_insert))) { - LOG_WARN("failed to check is direct insert into select", KR(ret)); + } else if (OB_FAIL(ObTableDirectInsertService::check_direct_insert(optimizer_context_, + *stmt, + is_direct_insert))) { + LOG_WARN("failed to check direct insert", KR(ret)); } else if (is_direct_insert) { // no need building index index_tid_array_size = 0; @@ -1653,8 +1656,14 @@ int ObDelUpdLogPlan::prepare_table_dml_info_basic(const ObDmlTableInfo& table_in uint64_t index_tid[OB_MAX_INDEX_PER_TABLE]; int64_t index_cnt = OB_MAX_INDEX_PER_TABLE; bool is_direct_insert = false; - if (OB_FAIL(is_direct_insert_into_select(is_direct_insert))) { - LOG_WARN("failed to check is direct insert into select", KR(ret)); + const ObDelUpdStmt *stmt = get_stmt(); + if (OB_ISNULL(stmt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", KR(ret), KP(stmt)); + } else if (OB_FAIL(ObTableDirectInsertService::check_direct_insert(optimizer_context_, + *stmt, + is_direct_insert))) { + LOG_WARN("failed to check direct insert", KR(ret)); } else if (is_direct_insert) { // no need building index index_cnt = 0; @@ -2063,28 +2072,3 @@ int ObDelUpdLogPlan::allocate_link_dml_as_top(ObLogicalOperator *&old_top) } return ret; } - -int ObDelUpdLogPlan::is_direct_insert_into_select(bool &result) -{ - int ret = OB_SUCCESS; - const ObDelUpdStmt *stmt = get_stmt(); - ObSQLSessionInfo* session_info = optimizer_context_.get_session_info(); - if (OB_ISNULL(stmt) || OB_ISNULL(session_info)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected null", KR(ret), KP(stmt), KP(session_info)); - } else if (stmt::T_INSERT == stmt->stmt_type_ - && static_cast(stmt)->value_from_select() - && GCONF._ob_enable_direct_load - && get_optimizer_context().get_global_hint().has_append() - && get_optimizer_context().use_pdml()) { // Currently direct-insert only supports pdml - // In direct-insert mode, index will be built by direct loader - bool auto_commit = false; - if (OB_FAIL(session_info->get_autocommit(auto_commit))) { - LOG_WARN("failed to get auto commit", KR(ret)); - } else if (auto_commit && !session_info->is_in_transaction()) { - LOG_TRACE("insert into select clause in direct-insert mode, no need building index"); - result = true; - } - } - return ret; -} diff --git a/src/sql/optimizer/ob_del_upd_log_plan.h b/src/sql/optimizer/ob_del_upd_log_plan.h index bb2d29b6c..33125b4f3 100644 --- a/src/sql/optimizer/ob_del_upd_log_plan.h +++ b/src/sql/optimizer/ob_del_upd_log_plan.h @@ -227,8 +227,6 @@ protected: virtual int generate_normal_raw_plan() override; virtual int generate_dblink_raw_plan() override; -private: - int is_direct_insert_into_select(bool &result); private: DISALLOW_COPY_AND_ASSIGN(ObDelUpdLogPlan); diff --git a/src/sql/optimizer/ob_explain_note.h b/src/sql/optimizer/ob_explain_note.h index d9415ab46..c5771dd0f 100644 --- a/src/sql/optimizer/ob_explain_note.h +++ b/src/sql/optimizer/ob_explain_note.h @@ -31,6 +31,7 @@ namespace sql #define PARALLEL_ENABLED_BY_SESSION "Degree of Parallelism is %ld because of session" #define PARALLEL_ENABLED_BY_TABLE_PROPERTY "Degree of Parallelisim is %ld because of table property" #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" } } diff --git a/src/sql/optimizer/ob_optimizer.cpp b/src/sql/optimizer/ob_optimizer.cpp index fad9f9a77..98c08d8f2 100644 --- a/src/sql/optimizer/ob_optimizer.cpp +++ b/src/sql/optimizer/ob_optimizer.cpp @@ -22,6 +22,7 @@ #include "sql/optimizer/ob_logical_operator.h" #include "common/ob_smart_call.h" #include "sql/ob_optimizer_trace_impl.h" +#include "sql/engine/cmd/ob_table_direct_insert_service.h" using namespace oceanbase; using namespace sql; using namespace oceanbase::common; @@ -675,6 +676,12 @@ int ObOptimizer::init_env_info(ObDMLStmt &stmt) ctx_.set_parallel(1); ctx_.add_plan_note(PARALLEL_DISABLED_BY_PL_UDF_DAS, 1); } + bool is_direct_insert = false; + if (OB_FAIL(ObTableDirectInsertService::check_direct_insert(ctx_, stmt, is_direct_insert))) { + LOG_WARN("failed to check direct insert", KR(ret)); + } else if (is_direct_insert) { + ctx_.add_plan_note(DIRECT_MODE_INSERT_INTO_SELECT); + } } // init column usage info