Completing the information of insert into select clause in direct-mode
This commit is contained in:
@ -10,6 +10,8 @@
|
|||||||
#include "observer/table_load/ob_table_load_store.h"
|
#include "observer/table_load/ob_table_load_store.h"
|
||||||
#include "sql/engine/ob_exec_context.h"
|
#include "sql/engine/ob_exec_context.h"
|
||||||
#include "sql/engine/ob_physical_plan.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
|
namespace oceanbase
|
||||||
{
|
{
|
||||||
@ -17,6 +19,36 @@ using namespace observer;
|
|||||||
|
|
||||||
namespace sql
|
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<const ObInsertStmt &>(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)
|
bool ObTableDirectInsertService::is_direct_insert(const ObPhysicalPlan &phy_plan)
|
||||||
{
|
{
|
||||||
return (phy_plan.get_enable_append() && (0 != phy_plan.get_append_table_id()));
|
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));
|
LOG_WARN("failed to get auto commit", KR(ret));
|
||||||
} else if (!auto_commit || session->is_in_transaction()) {
|
} else if (!auto_commit || session->is_in_transaction()) {
|
||||||
ret = OB_NOT_SUPPORTED;
|
ret = OB_NOT_SUPPORTED;
|
||||||
LOG_WARN("using direct-insert within a transaction is not supported",
|
LOG_USER_ERROR(OB_NOT_SUPPORTED, "using direct-insert within a transaction is");
|
||||||
KR(ret), K(auto_commit), K(session->is_in_transaction()));
|
|
||||||
} else {
|
} else {
|
||||||
ObTableDirectInsertCtx &table_direct_insert_ctx = ctx.get_table_direct_insert_ctx();
|
ObTableDirectInsertCtx &table_direct_insert_ctx = ctx.get_table_direct_insert_ctx();
|
||||||
uint64_t table_id = phy_plan.get_append_table_id();
|
uint64_t table_id = phy_plan.get_append_table_id();
|
||||||
|
|||||||
@ -12,10 +12,15 @@ namespace sql
|
|||||||
{
|
{
|
||||||
class ObExecContext;
|
class ObExecContext;
|
||||||
class ObPhysicalPlan;
|
class ObPhysicalPlan;
|
||||||
|
class ObOptimizerContext;
|
||||||
|
class ObDMLStmt;
|
||||||
|
|
||||||
class ObTableDirectInsertService
|
class ObTableDirectInsertService
|
||||||
{
|
{
|
||||||
public:
|
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);
|
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
|
// 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);
|
static int start_direct_insert(ObExecContext &ctx, ObPhysicalPlan &plan);
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include "sql/resolver/dml/ob_merge_stmt.h"
|
#include "sql/resolver/dml/ob_merge_stmt.h"
|
||||||
#include "sql/rewrite/ob_transform_utils.h"
|
#include "sql/rewrite/ob_transform_utils.h"
|
||||||
#include "sql/dblink/ob_dblink_utils.h"
|
#include "sql/dblink/ob_dblink_utils.h"
|
||||||
|
#include "sql/engine/cmd/ob_table_direct_insert_service.h"
|
||||||
|
|
||||||
using namespace oceanbase;
|
using namespace oceanbase;
|
||||||
using namespace sql;
|
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())) {
|
if (OB_ISNULL(stmt) || OB_ISNULL(schema_guard = optimizer_context_.get_schema_guard())) {
|
||||||
ret = OB_ERR_UNEXPECTED;
|
ret = OB_ERR_UNEXPECTED;
|
||||||
LOG_WARN("schema guard is nullptr", K(ret), K(stmt), K(schema_guard));
|
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))) {
|
} else if (OB_FAIL(ObTableDirectInsertService::check_direct_insert(optimizer_context_,
|
||||||
LOG_WARN("failed to check is direct insert into select", KR(ret));
|
*stmt,
|
||||||
|
is_direct_insert))) {
|
||||||
|
LOG_WARN("failed to check direct insert", KR(ret));
|
||||||
} else if (is_direct_insert) {
|
} else if (is_direct_insert) {
|
||||||
// no need building index
|
// no need building index
|
||||||
index_tid_array_size = 0;
|
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];
|
uint64_t index_tid[OB_MAX_INDEX_PER_TABLE];
|
||||||
int64_t index_cnt = OB_MAX_INDEX_PER_TABLE;
|
int64_t index_cnt = OB_MAX_INDEX_PER_TABLE;
|
||||||
bool is_direct_insert = false;
|
bool is_direct_insert = false;
|
||||||
if (OB_FAIL(is_direct_insert_into_select(is_direct_insert))) {
|
const ObDelUpdStmt *stmt = get_stmt();
|
||||||
LOG_WARN("failed to check is direct insert into select", KR(ret));
|
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) {
|
} else if (is_direct_insert) {
|
||||||
// no need building index
|
// no need building index
|
||||||
index_cnt = 0;
|
index_cnt = 0;
|
||||||
@ -2063,28 +2072,3 @@ int ObDelUpdLogPlan::allocate_link_dml_as_top(ObLogicalOperator *&old_top)
|
|||||||
}
|
}
|
||||||
return ret;
|
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<const ObInsertStmt*>(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;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -227,8 +227,6 @@ protected:
|
|||||||
virtual int generate_normal_raw_plan() override;
|
virtual int generate_normal_raw_plan() override;
|
||||||
virtual int generate_dblink_raw_plan() override;
|
virtual int generate_dblink_raw_plan() override;
|
||||||
|
|
||||||
private:
|
|
||||||
int is_direct_insert_into_select(bool &result);
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(ObDelUpdLogPlan);
|
DISALLOW_COPY_AND_ASSIGN(ObDelUpdLogPlan);
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,7 @@ namespace sql
|
|||||||
#define PARALLEL_ENABLED_BY_SESSION "Degree of Parallelism is %ld because of session"
|
#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_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 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"
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
#include "sql/optimizer/ob_logical_operator.h"
|
#include "sql/optimizer/ob_logical_operator.h"
|
||||||
#include "common/ob_smart_call.h"
|
#include "common/ob_smart_call.h"
|
||||||
#include "sql/ob_optimizer_trace_impl.h"
|
#include "sql/ob_optimizer_trace_impl.h"
|
||||||
|
#include "sql/engine/cmd/ob_table_direct_insert_service.h"
|
||||||
using namespace oceanbase;
|
using namespace oceanbase;
|
||||||
using namespace sql;
|
using namespace sql;
|
||||||
using namespace oceanbase::common;
|
using namespace oceanbase::common;
|
||||||
@ -675,6 +676,12 @@ int ObOptimizer::init_env_info(ObDMLStmt &stmt)
|
|||||||
ctx_.set_parallel(1);
|
ctx_.set_parallel(1);
|
||||||
ctx_.add_plan_note(PARALLEL_DISABLED_BY_PL_UDF_DAS, 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
|
// init column usage info
|
||||||
|
|||||||
Reference in New Issue
Block a user