init push
This commit is contained in:
1759
src/sql/engine/cmd/ob_alter_system_executor.cpp
Normal file
1759
src/sql/engine/cmd/ob_alter_system_executor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
158
src/sql/engine/cmd/ob_alter_system_executor.h
Normal file
158
src/sql/engine/cmd/ob_alter_system_executor.h
Normal file
@ -0,0 +1,158 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_ENGINE_CMD_OB_ALTER_SYSTEM_EXECUTOR_
|
||||
#define OCEANBASE_SQL_ENGINE_CMD_OB_ALTER_SYSTEM_EXECUTOR_
|
||||
|
||||
#include "share/ob_define.h"
|
||||
#include "sql/resolver/cmd/ob_alter_system_stmt.h"
|
||||
#include "sql/resolver/cmd/ob_clear_balance_task_stmt.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObAdminServerStmt;
|
||||
class ObAdminZoneStmt;
|
||||
class ObBootstrapStmt;
|
||||
|
||||
#define DEF_SIMPLE_EXECUTOR(name) \
|
||||
class name##Executor { \
|
||||
public: \
|
||||
name##Executor() \
|
||||
{} \
|
||||
virtual ~name##Executor() \
|
||||
{} \
|
||||
int execute(ObExecContext& ctx, name##Stmt& stmt); \
|
||||
\
|
||||
private: \
|
||||
DISALLOW_COPY_AND_ASSIGN(name##Executor); \
|
||||
}
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObAdminServer);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObAdminZone);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObFreeze);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObFlushCache);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObFlushKVCache);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObFlushIlogCache);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObFlushDagWarnings);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObLoadBaseline);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObSwitchReplicaRole);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObSwitchRSRole);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObDropReplica);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObChangeReplica);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObMigrateReplica);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObReportReplica);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObRecycleReplica);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObAdminMerge);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObClearRoottable);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObRefreshSchema);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObRefreshMemStat);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObSetConfig);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObClearLocationCache);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObReloadGts);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObReloadUnit);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObReloadServer);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObReloadZone);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObClearMergeError);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObMigrateUnit);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObUpgradeVirtualSchema);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObAdminUpgradeCmd);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObAdminRollingUpgradeCmd);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObRunJob);
|
||||
DEF_SIMPLE_EXECUTOR(ObRunUpgradeJob);
|
||||
DEF_SIMPLE_EXECUTOR(ObStopUpgradeJob);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObBootstrap);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObSetTP);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObRefreshTimeZoneInfo);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObEnableSqlThrottle);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObDisableSqlThrottle);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObSetDiskValid);
|
||||
DEF_SIMPLE_EXECUTOR(ObClearBalanceTask);
|
||||
DEF_SIMPLE_EXECUTOR(ObAddDisk);
|
||||
DEF_SIMPLE_EXECUTOR(ObDropDisk);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObArchiveLog);
|
||||
DEF_SIMPLE_EXECUTOR(ObBackupDatabase);
|
||||
DEF_SIMPLE_EXECUTOR(ObBackupManage);
|
||||
DEF_SIMPLE_EXECUTOR(ObBackupSetEncryption);
|
||||
DEF_SIMPLE_EXECUTOR(ObBackupSetDecryption);
|
||||
|
||||
class ObCancelTaskExecutor {
|
||||
public:
|
||||
ObCancelTaskExecutor()
|
||||
{}
|
||||
virtual ~ObCancelTaskExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObCancelTaskStmt& stmt);
|
||||
|
||||
private:
|
||||
int parse_task_id(const common::ObString& task_id_str, share::ObTaskId& task_id);
|
||||
int fetch_sys_task_info(ObExecContext& ctx, const common::ObString& task_id, common::ObAddr& task_server);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObCancelTaskExecutor);
|
||||
};
|
||||
|
||||
class ObChangeTenantExecutor {
|
||||
public:
|
||||
ObChangeTenantExecutor()
|
||||
{}
|
||||
virtual ~ObChangeTenantExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObChangeTenantStmt& stmt);
|
||||
|
||||
private:
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObChangeTenantExecutor);
|
||||
};
|
||||
|
||||
#undef DEF_SIMPLE_EXECUTOR
|
||||
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
#endif // OCEANBASE_SQL_ENGINE_CMD_OB_ALTER_SYSTEM_EXECUTOR_
|
||||
56
src/sql/engine/cmd/ob_baseline_executor.cpp
Normal file
56
src/sql/engine/cmd/ob_baseline_executor.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
|
||||
#include "sql/engine/cmd/ob_baseline_executor.h"
|
||||
|
||||
#include "lib/string/ob_string.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
#include "share/schema/ob_schema_getter_guard.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
#include "observer/ob_server_struct.h"
|
||||
#include "sql/resolver/ddl/ob_alter_baseline_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/resolver/ob_schema_checker.h"
|
||||
#include "sql/plan_cache/ob_cache_object_factory.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace share::schema;
|
||||
using namespace obrpc;
|
||||
namespace sql {
|
||||
int ObAlterBaselineExecutor::execute(ObExecContext& ctx, ObAlterBaselineStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
ObAlterPlanBaselineArg& arg = stmt.alter_baseline_arg_;
|
||||
if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->alter_plan_baseline(arg))) {
|
||||
LOG_WARN("rpc proxy alter baseline failed", "dst", common_rpc_proxy->get_server(), K(ret));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
47
src/sql/engine/cmd/ob_baseline_executor.h
Normal file
47
src/sql/engine/cmd/ob_baseline_executor.h
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_OB_BASELINE_EXECUTOR_H_
|
||||
#define OCEANBASE_SQL_OB_BASELINE_EXECUTOR_H_
|
||||
|
||||
#include "lib/container/ob_vector.h"
|
||||
#include "sql/parser/parse_node.h"
|
||||
#include "sql/resolver/ob_stmt_type.h"
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
class ObString;
|
||||
}
|
||||
namespace share {
|
||||
namespace schema {}
|
||||
} // namespace share
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObAlterBaselineStmt;
|
||||
class ObLogPlan;
|
||||
class ObDMLStmt;
|
||||
class ObOptimizerContext;
|
||||
|
||||
class ObAlterBaselineExecutor {
|
||||
public:
|
||||
ObAlterBaselineExecutor()
|
||||
{}
|
||||
virtual ~ObAlterBaselineExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObAlterBaselineStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObAlterBaselineExecutor);
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif // OCEANBASE_SQL_OB_BASELINE_EXECUTOR_H_
|
||||
259
src/sql/engine/cmd/ob_database_executor.cpp
Normal file
259
src/sql/engine/cmd/ob_database_executor.cpp
Normal file
@ -0,0 +1,259 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "sql/engine/cmd/ob_database_executor.h"
|
||||
#include "sql/resolver/ddl/ob_create_database_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_use_database_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_alter_database_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_drop_database_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_purge_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "share/ob_worker.h"
|
||||
#include "share/ob_cluster_info_proxy.h"
|
||||
#include "rootserver/ob_root_utils.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
namespace sql {
|
||||
ObCreateDatabaseExecutor::ObCreateDatabaseExecutor()
|
||||
{}
|
||||
|
||||
ObCreateDatabaseExecutor::~ObCreateDatabaseExecutor()
|
||||
{}
|
||||
|
||||
int ObCreateDatabaseExecutor::execute(ObExecContext& ctx, ObCreateDatabaseStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObCreateDatabaseArg& create_database_arg = stmt.get_create_database_arg();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
SQL_ENG_LOG(WARN, "fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObCreateDatabaseArg&>(create_database_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy) || OB_ISNULL(ctx.get_physical_plan_ctx())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "fail to get physical plan ctx", K(ret), K(ctx), K(common_rpc_proxy));
|
||||
} else {
|
||||
obrpc::UInt64 database_id(0);
|
||||
if (OB_FAIL(common_rpc_proxy->create_database(create_database_arg, database_id))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy create table failed", K(ret));
|
||||
} else {
|
||||
ctx.get_physical_plan_ctx()->set_affected_rows(1);
|
||||
}
|
||||
}
|
||||
SQL_ENG_LOG(INFO, "finish execute create database.", K(ret), K(stmt));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
ObUseDatabaseExecutor::ObUseDatabaseExecutor()
|
||||
{}
|
||||
|
||||
ObUseDatabaseExecutor::~ObUseDatabaseExecutor()
|
||||
{}
|
||||
|
||||
int ObUseDatabaseExecutor::execute(ObExecContext& ctx, ObUseDatabaseStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
if (OB_ISNULL(session = ctx.get_my_session())) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "session is NULL");
|
||||
} else {
|
||||
const bool is_oracle_mode = share::is_oracle_mode();
|
||||
const bool is_oceanbase_db = OB_SYS_DATABASE_ID == extract_pure_id(stmt.get_db_id());
|
||||
if (session->is_tenant_changed() && !is_oceanbase_db) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
SQL_ENG_LOG(WARN,
|
||||
"tenant changed, access non oceanbase database not allowed",
|
||||
K(ret),
|
||||
K(stmt),
|
||||
"login_tenant_id",
|
||||
session->get_login_tenant_id(),
|
||||
"effective_tenant_id",
|
||||
session->get_effective_tenant_id());
|
||||
LOG_USER_ERROR(OB_OP_NOT_ALLOW, "tenant changed, access non oceanbase database");
|
||||
} else if (is_oracle_mode && is_oceanbase_db) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
SQL_ENG_LOG(WARN,
|
||||
"cannot access oceanbase database on tenant with oracle compatiblity",
|
||||
K(ret),
|
||||
"effective_tenant_id",
|
||||
session->get_effective_tenant_id());
|
||||
LOG_USER_ERROR(OB_OP_NOT_ALLOW, "access oceanbase database");
|
||||
} else {
|
||||
ObCollationType db_coll_type = ObCharset::collation_type(stmt.get_db_collation());
|
||||
if (OB_UNLIKELY(CS_TYPE_INVALID == db_coll_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "invalid collation", K(ret), K(stmt.get_db_name()), K(stmt.get_db_collation()));
|
||||
} else if (OB_FAIL(session->set_default_database(stmt.get_db_name(), db_coll_type))) {
|
||||
SQL_ENG_LOG(WARN,
|
||||
"fail to set default database",
|
||||
K(ret),
|
||||
K(stmt.get_db_name()),
|
||||
K(stmt.get_db_collation()),
|
||||
K(db_coll_type));
|
||||
} else {
|
||||
session->set_db_priv_set(stmt.get_db_priv_set());
|
||||
SQL_ENG_LOG(INFO, "use default database", "db", stmt.get_db_name());
|
||||
session->set_database_id(stmt.get_db_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//////////////////
|
||||
ObAlterDatabaseExecutor::ObAlterDatabaseExecutor()
|
||||
{}
|
||||
|
||||
ObAlterDatabaseExecutor::~ObAlterDatabaseExecutor()
|
||||
{}
|
||||
|
||||
int ObAlterDatabaseExecutor::execute(ObExecContext& ctx, ObAlterDatabaseStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObAlterDatabaseArg& alter_database_arg = stmt.get_alter_database_arg();
|
||||
ObString first_stmt;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
if (OB_ISNULL(session = ctx.get_my_session())) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "session is NULL");
|
||||
} else if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
SQL_ENG_LOG(WARN, "fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObAlterDatabaseArg&>(alter_database_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed");
|
||||
} else if (OB_FAIL(common_rpc_proxy->alter_database(alter_database_arg))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy alter table failed", K(ret));
|
||||
} else if (!stmt.get_alter_option_set().has_member(obrpc::ObAlterDatabaseArg::COLLATION_TYPE)) {
|
||||
// do nothing
|
||||
} else if (0 == stmt.get_database_name().compare(session->get_database_name())) {
|
||||
const int64_t db_coll = static_cast<int64_t>(stmt.get_collation_type());
|
||||
if (OB_FAIL(session->update_sys_variable(share::SYS_VAR_CHARACTER_SET_DATABASE, db_coll))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys variable", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(share::SYS_VAR_COLLATION_DATABASE, db_coll))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys variable", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//////////////////
|
||||
ObDropDatabaseExecutor::ObDropDatabaseExecutor()
|
||||
{}
|
||||
|
||||
ObDropDatabaseExecutor::~ObDropDatabaseExecutor()
|
||||
{}
|
||||
|
||||
int ObDropDatabaseExecutor::execute(ObExecContext& ctx, ObDropDatabaseStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObDropDatabaseArg& drop_database_arg = stmt.get_drop_database_arg();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
SQL_ENG_LOG(WARN, "fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObDropDatabaseArg&>(drop_database_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy) || OB_ISNULL(ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "failt to get my session", K(ctx), K(common_rpc_proxy));
|
||||
} else {
|
||||
obrpc::UInt64 affected_row(0);
|
||||
if (OB_FAIL(common_rpc_proxy->drop_database(drop_database_arg, affected_row))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy drop table failed", "timeout", THIS_WORKER.get_timeout_remain(), K(ret));
|
||||
} else if (OB_ISNULL(ctx.get_physical_plan_ctx())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "fail to get physical plan ctx", K(ret), K(ctx));
|
||||
} else {
|
||||
ObString null_string;
|
||||
ObNameCaseMode case_mode = OB_NAME_CASE_INVALID;
|
||||
if (OB_FAIL(ctx.get_my_session()->get_name_case_mode(case_mode))) {
|
||||
SQL_ENG_LOG(WARN, "fail to get name case mode from session", K(ret));
|
||||
} else if (ObCharset::case_mode_equal(
|
||||
case_mode, ctx.get_my_session()->get_database_name(), drop_database_arg.database_name_)) {
|
||||
ObCollationType server_coll_type = ObCharset::collation_type(stmt.get_server_collation());
|
||||
if (OB_UNLIKELY(CS_TYPE_INVALID == server_coll_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "invalid collation", K(ret), K(stmt.get_server_collation()));
|
||||
} else if (OB_FAIL(ctx.get_my_session()->set_default_database(null_string, server_coll_type))) {
|
||||
SQL_ENG_LOG(
|
||||
WARN, "fail to set default database", K(ret), K(stmt.get_server_collation()), K(server_coll_type));
|
||||
} else {
|
||||
ctx.get_physical_plan_ctx()->set_affected_rows(affected_row);
|
||||
ctx.get_my_session()->set_database_id(OB_INVALID_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
SQL_ENG_LOG(INFO, "finish execute drop database.", K(ret), K(stmt));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPurgeDatabaseExecutor::execute(ObExecContext& ctx, ObPurgeDatabaseStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const obrpc::ObPurgeDatabaseArg& purge_database_arg = stmt.get_purge_database_arg();
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
SQL_ENG_LOG(WARN, "fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObPurgeDatabaseArg&>(purge_database_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->purge_database(purge_database_arg))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy purge database failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
99
src/sql/engine/cmd/ob_database_executor.h
Normal file
99
src/sql/engine/cmd/ob_database_executor.h
Normal file
@ -0,0 +1,99 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SRC_SQL_ENGINE_CMD_OB_DATABASE_EXECUTOR_H_
|
||||
#define OCEANBASE_SRC_SQL_ENGINE_CMD_OB_DATABASE_EXECUTOR_H_
|
||||
#include "share/ob_define.h"
|
||||
#include "share/schema/ob_schema_getter_guard.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObCreateDatabaseStmt;
|
||||
class ObDropDatabaseStmt;
|
||||
class ObUseDatabaseStmt;
|
||||
class ObAlterDatabaseStmt;
|
||||
class ObFlashBackDatabaseStmt;
|
||||
class ObPurgeDatabaseStmt;
|
||||
class ObCreateDatabaseExecutor {
|
||||
public:
|
||||
ObCreateDatabaseExecutor();
|
||||
virtual ~ObCreateDatabaseExecutor();
|
||||
int execute(ObExecContext& ctx, ObCreateDatabaseStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObCreateDatabaseExecutor);
|
||||
};
|
||||
|
||||
///////////////////////
|
||||
class ObUseDatabaseExecutor {
|
||||
public:
|
||||
ObUseDatabaseExecutor();
|
||||
virtual ~ObUseDatabaseExecutor();
|
||||
int execute(ObExecContext& ctx, ObUseDatabaseStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObUseDatabaseExecutor);
|
||||
};
|
||||
|
||||
///////////////////////
|
||||
class ObAlterDatabaseExecutor {
|
||||
public:
|
||||
ObAlterDatabaseExecutor();
|
||||
virtual ~ObAlterDatabaseExecutor();
|
||||
int execute(ObExecContext& ctx, ObAlterDatabaseStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObAlterDatabaseExecutor);
|
||||
};
|
||||
|
||||
/////////////////////
|
||||
class ObDropDatabaseExecutor {
|
||||
public:
|
||||
ObDropDatabaseExecutor();
|
||||
virtual ~ObDropDatabaseExecutor();
|
||||
int execute(ObExecContext& ctx, ObDropDatabaseStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObDropDatabaseExecutor);
|
||||
};
|
||||
|
||||
/* *
|
||||
*
|
||||
* */
|
||||
class ObFlashBackDatabaseExecutor {
|
||||
public:
|
||||
ObFlashBackDatabaseExecutor()
|
||||
{}
|
||||
virtual ~ObFlashBackDatabaseExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObFlashBackDatabaseStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObFlashBackDatabaseExecutor);
|
||||
};
|
||||
|
||||
class ObPurgeDatabaseExecutor {
|
||||
public:
|
||||
ObPurgeDatabaseExecutor()
|
||||
{}
|
||||
virtual ~ObPurgeDatabaseExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObPurgeDatabaseStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObPurgeDatabaseExecutor);
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif /* OCEANBASE_SRC_SQL_ENGINE_CMD_OB_DATABASE_EXECUTOR_H_ */
|
||||
76
src/sql/engine/cmd/ob_dblink_executor.cpp
Normal file
76
src/sql/engine/cmd/ob_dblink_executor.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "sql/engine/cmd/ob_dblink_executor.h"
|
||||
#include "sql/resolver/ddl/ob_create_dblink_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_drop_dblink_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "share/ob_worker.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
namespace sql {
|
||||
|
||||
int ObCreateDbLinkExecutor::execute(ObExecContext& ctx, ObCreateDbLinkStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObCreateDbLinkArg& create_dblink_arg = stmt.get_create_dblink_arg();
|
||||
const_cast<obrpc::ObCreateDbLinkArg&>(create_dblink_arg).ddl_stmt_str_ = stmt.get_sql_stmt();
|
||||
|
||||
if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy) || OB_ISNULL(ctx.get_physical_plan_ctx())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "fail to get physical plan ctx", K(ret), K(ctx), K(common_rpc_proxy));
|
||||
} else if (OB_FAIL(common_rpc_proxy->create_dblink(create_dblink_arg))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy create dblink failed", K(ret));
|
||||
} else {
|
||||
ctx.get_physical_plan_ctx()->set_affected_rows(1);
|
||||
}
|
||||
SQL_ENG_LOG(INFO, "finish execute create dblink.", K(ret), K(stmt));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDropDbLinkExecutor::execute(ObExecContext& ctx, ObDropDbLinkStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObDropDbLinkArg& drop_dblink_arg = stmt.get_drop_dblink_arg();
|
||||
const_cast<obrpc::ObDropDbLinkArg&>(drop_dblink_arg).ddl_stmt_str_ = stmt.get_sql_stmt();
|
||||
|
||||
if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy) || OB_ISNULL(ctx.get_physical_plan_ctx())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "fail to get physical plan ctx", K(ret), K(ctx), K(common_rpc_proxy));
|
||||
} else if (OB_FAIL(common_rpc_proxy->drop_dblink(drop_dblink_arg))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy drop dblink failed", K(ret));
|
||||
} else {
|
||||
ctx.get_physical_plan_ctx()->set_affected_rows(1);
|
||||
}
|
||||
SQL_ENG_LOG(INFO, "finish execute drop dblink.", K(ret), K(stmt));
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
49
src/sql/engine/cmd/ob_dblink_executor.h
Normal file
49
src/sql/engine/cmd/ob_dblink_executor.h
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SRC_SQL_ENGINE_CMD_OB_DBLINK_EXECUTOR_H_
|
||||
#define OCEANBASE_SRC_SQL_ENGINE_CMD_OB_DBLINK_EXECUTOR_H_
|
||||
#include "share/ob_define.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObCreateDbLinkStmt;
|
||||
class ObDropDbLinkStmt;
|
||||
|
||||
class ObCreateDbLinkExecutor {
|
||||
public:
|
||||
ObCreateDbLinkExecutor()
|
||||
{}
|
||||
virtual ~ObCreateDbLinkExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObCreateDbLinkStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObCreateDbLinkExecutor);
|
||||
};
|
||||
|
||||
class ObDropDbLinkExecutor {
|
||||
public:
|
||||
ObDropDbLinkExecutor()
|
||||
{}
|
||||
virtual ~ObDropDbLinkExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObDropDbLinkStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObDropDbLinkExecutor);
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif /* OCEANBASE_SRC_SQL_ENGINE_CMD_OB_DBLINK_EXECUTOR_H_ */
|
||||
298
src/sql/engine/cmd/ob_dcl_executor.cpp
Normal file
298
src/sql/engine/cmd/ob_dcl_executor.cpp
Normal file
@ -0,0 +1,298 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/engine/cmd/ob_dcl_executor.h"
|
||||
|
||||
#include "lib/encrypt/ob_encrypted_helper.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/resolver/dcl/ob_grant_stmt.h"
|
||||
#include "sql/resolver/dcl/ob_revoke_stmt.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/engine/cmd/ob_user_cmd_executor.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace share::schema;
|
||||
namespace sql {
|
||||
|
||||
int ObGrantExecutor::execute(ObExecContext& ctx, ObGrantStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
ObSQLSessionInfo* session_info = NULL;
|
||||
const uint64_t tenant_id = stmt.get_tenant_id();
|
||||
const ObStrings& users = stmt.get_users();
|
||||
ObIAllocator& allocator = ctx.get_allocator();
|
||||
obrpc::ObGrantArg& arg = static_cast<obrpc::ObGrantArg&>(stmt.get_ddl_arg());
|
||||
const bool is_role = arg.roles_.count() > 0;
|
||||
|
||||
if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_ISNULL(session_info = ctx.get_my_session())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("Get my session error");
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (!is_role) {
|
||||
ObString user_name;
|
||||
ObString host_name;
|
||||
ObString pwd;
|
||||
ObString need_enc;
|
||||
// i += 4, each with user_name, pwd, need_enc
|
||||
if (OB_UNLIKELY(users.count() <= 0) || OB_UNLIKELY(0 != users.count() % 4)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("Resolve users error. Users should have user and pwd", "ObStrings count", users.count(), K(ret));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < users.count(); i += 4) {
|
||||
if (OB_FAIL(users.get_string(i, user_name))) {
|
||||
LOG_WARN("Get string from ObStrings error", "count", users.count(), K(i), K(ret));
|
||||
} else if (OB_FAIL(users.get_string(i + 1, host_name))) {
|
||||
LOG_WARN("Get string from ObStrings error", "count", users.count(), K(i), K(ret));
|
||||
} else if (OB_FAIL(users.get_string(i + 2, pwd))) {
|
||||
LOG_WARN("Get string from ObStrings error", "count", users.count(), K(i), K(ret));
|
||||
} else if (OB_FAIL(users.get_string(i + 3, need_enc))) {
|
||||
LOG_WARN("Get string from ObStrings error", "count", users.count(), K(i), K(ret));
|
||||
} else {
|
||||
if (OB_FAIL(arg.users_passwd_.push_back(user_name))) {
|
||||
LOG_WARN("failed to add user", K(ret));
|
||||
} else if (OB_FAIL(arg.hosts_.push_back(host_name))) {
|
||||
LOG_WARN("failed to add user", K(ret));
|
||||
} else if (ObString::make_string("YES") == need_enc) {
|
||||
ObString pwd_enc;
|
||||
if (pwd.length() > 0) {
|
||||
char* enc_buf = NULL;
|
||||
if (NULL == (enc_buf = static_cast<char*>(allocator.alloc(ENC_BUF_LEN)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_ERROR("Failed to allocate memory", K(ret), K(ENC_BUF_LEN));
|
||||
} else if (OB_FAIL(ObCreateUserExecutor::encrypt_passwd(pwd, pwd_enc, enc_buf, ENC_BUF_LEN))) {
|
||||
LOG_WARN("Encrypt password failed", K(ret));
|
||||
} else {
|
||||
} // do nothing
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(arg.users_passwd_.push_back(pwd_enc))) {
|
||||
LOG_WARN("failed to add password", K(ret));
|
||||
} else {
|
||||
} // do nothing
|
||||
} else {
|
||||
if (OB_FAIL(arg.users_passwd_.push_back(pwd))) {
|
||||
LOG_WARN("failed to add password", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
arg.tenant_id_ = tenant_id;
|
||||
arg.db_ = stmt.get_database_name();
|
||||
arg.table_ = stmt.get_table_name();
|
||||
arg.priv_set_ = stmt.get_priv_set();
|
||||
arg.priv_level_ = stmt.get_grant_level();
|
||||
arg.need_create_user_ = stmt.get_need_create_user();
|
||||
arg.has_create_user_priv_ = session_info->get_user_priv_set() & OB_PRIV_CREATE_USER;
|
||||
arg.ddl_stmt_str_ = stmt.get_sql_stmt();
|
||||
arg.option_ = stmt.get_option();
|
||||
arg.object_type_ = stmt.get_object_type();
|
||||
arg.object_id_ = stmt.get_object_id();
|
||||
arg.grantor_id_ = stmt.get_grantor_id();
|
||||
arg.ins_col_ids_ = stmt.get_ins_col_ids();
|
||||
arg.upd_col_ids_ = stmt.get_upd_col_ids();
|
||||
arg.ref_col_ids_ = stmt.get_ref_col_ids();
|
||||
arg.is_inner_ = session_info->is_inner();
|
||||
if (OB_FAIL(common_rpc_proxy->grant(arg))) {
|
||||
LOG_WARN("Grant privileges to user error", K(ret), K(arg));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRevokeExecutor::execute(ObExecContext& ctx, ObRevokeStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
|
||||
if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed");
|
||||
} else {
|
||||
switch (stmt.get_grant_level()) {
|
||||
case OB_PRIV_USER_LEVEL: {
|
||||
if (OB_FAIL(revoke_user(common_rpc_proxy, stmt))) {
|
||||
LOG_WARN("grant_revoke_user error", K(ret));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OB_PRIV_DB_LEVEL: {
|
||||
if (OB_FAIL(revoke_db(common_rpc_proxy, stmt))) {
|
||||
LOG_WARN("grant_revoke_user error", K(ret));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OB_PRIV_TABLE_LEVEL: {
|
||||
if (OB_FAIL(revoke_table(common_rpc_proxy, stmt))) {
|
||||
LOG_WARN("grant_revoke_user error", K(ret));
|
||||
}
|
||||
break;
|
||||
case OB_PRIV_SYS_ORACLE_LEVEL: {
|
||||
if (OB_FAIL(revoke_sys_priv(common_rpc_proxy, stmt))) {
|
||||
LOG_WARN("grant_revoke_user error", K(ret));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
default: {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("Resolver may be error, invalid grant_level",
|
||||
"grant_level",
|
||||
ob_priv_level_str(stmt.get_grant_level()),
|
||||
K(ret));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRevokeExecutor::revoke_user(obrpc::ObCommonRpcProxy* rpc_proxy, ObRevokeStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(rpc_proxy)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("Input argument error", K(rpc_proxy), K(ret));
|
||||
} else {
|
||||
obrpc::ObRevokeUserArg& arg = static_cast<obrpc::ObRevokeUserArg&>(stmt.get_ddl_arg());
|
||||
arg.tenant_id_ = stmt.get_tenant_id();
|
||||
const ObIArray<uint64_t>& user_ids = stmt.get_users();
|
||||
const bool is_role = arg.role_ids_.count() > 0;
|
||||
if (is_role) {
|
||||
for (int i = 0; OB_SUCC(ret) && i < user_ids.count(); ++i) {
|
||||
arg.user_id_ = user_ids.at(i);
|
||||
if (OB_FAIL(rpc_proxy->revoke_user(arg))) {
|
||||
LOG_WARN("revoke user error", K(arg), K(ret));
|
||||
}
|
||||
}
|
||||
} else if (0 == user_ids.count()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("User ids is empty, resolver may be error", K(ret));
|
||||
} else {
|
||||
arg.revoke_all_ = stmt.get_revoke_all();
|
||||
arg.priv_set_ = stmt.get_priv_set();
|
||||
for (int i = 0; OB_SUCC(ret) && i < user_ids.count(); i++) {
|
||||
arg.user_id_ = user_ids.at(i);
|
||||
if (OB_FAIL(rpc_proxy->revoke_user(arg))) {
|
||||
LOG_WARN("revoke user error", K(arg), K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRevokeExecutor::revoke_db(obrpc::ObCommonRpcProxy* rpc_proxy, ObRevokeStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(rpc_proxy)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("Input argument error", K(rpc_proxy), K(ret));
|
||||
} else {
|
||||
obrpc::ObRevokeDBArg& arg = static_cast<obrpc::ObRevokeDBArg&>(stmt.get_ddl_arg());
|
||||
arg.tenant_id_ = stmt.get_tenant_id();
|
||||
arg.priv_set_ = stmt.get_priv_set();
|
||||
arg.db_ = stmt.get_database_name();
|
||||
const ObIArray<uint64_t>& user_ids = stmt.get_users();
|
||||
if (0 == user_ids.count()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("User ids is empty, resolver may be error", K(ret));
|
||||
} else {
|
||||
for (int i = 0; OB_SUCC(ret) && i < user_ids.count(); i++) {
|
||||
arg.user_id_ = user_ids.at(i);
|
||||
if (OB_FAIL(rpc_proxy->revoke_database(arg))) {
|
||||
LOG_WARN("revoke user error", K(arg), K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRevokeExecutor::revoke_table(obrpc::ObCommonRpcProxy* rpc_proxy, ObRevokeStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(rpc_proxy)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("Input argument error", K(rpc_proxy), K(ret));
|
||||
} else {
|
||||
obrpc::ObRevokeTableArg& arg = static_cast<obrpc::ObRevokeTableArg&>(stmt.get_ddl_arg());
|
||||
arg.tenant_id_ = stmt.get_tenant_id();
|
||||
arg.priv_set_ = stmt.get_priv_set();
|
||||
arg.db_ = stmt.get_database_name();
|
||||
arg.table_ = stmt.get_table_name();
|
||||
arg.obj_id_ = stmt.get_obj_id();
|
||||
arg.obj_type_ = static_cast<uint64_t>(stmt.get_object_type());
|
||||
arg.grantor_id_ = stmt.get_grantor_id();
|
||||
arg.revoke_all_ora_ = stmt.get_revoke_all_ora();
|
||||
|
||||
const ObIArray<uint64_t>& user_ids = stmt.get_users();
|
||||
if (0 == user_ids.count()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("User ids is empty, resolver may be error", K(ret));
|
||||
} else {
|
||||
for (int i = 0; OB_SUCC(ret) && i < user_ids.count(); i++) {
|
||||
arg.user_id_ = user_ids.at(i);
|
||||
if (OB_FAIL(rpc_proxy->revoke_table(arg))) {
|
||||
LOG_WARN("revoke user error", K(arg), K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRevokeExecutor::revoke_sys_priv(obrpc::ObCommonRpcProxy* rpc_proxy, ObRevokeStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(rpc_proxy)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("Input argument error", K(rpc_proxy), K(ret));
|
||||
} else {
|
||||
obrpc::ObRevokeSysPrivArg& arg = static_cast<obrpc::ObRevokeSysPrivArg&>(stmt.get_ddl_arg());
|
||||
arg.tenant_id_ = stmt.get_tenant_id();
|
||||
const ObIArray<uint64_t>& user_ids = stmt.get_users();
|
||||
if (0 == user_ids.count()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("User ids is empty, resolver may be error", K(ret));
|
||||
} else {
|
||||
arg.ddl_stmt_str_ = stmt.get_sql_stmt();
|
||||
for (int i = 0; OB_SUCC(ret) && i < user_ids.count(); i++) {
|
||||
arg.grantee_id_ = user_ids.at(i);
|
||||
if (OB_FAIL(rpc_proxy->revoke_sys_priv(arg))) {
|
||||
LOG_WARN("revoke user error", K(arg), K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
61
src/sql/engine/cmd/ob_dcl_executor.h
Normal file
61
src/sql/engine/cmd/ob_dcl_executor.h
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_ENGINE_CMD_OB_DCL_EXECUTOR_
|
||||
#define OCEANBASE_SQL_ENGINE_CMD_OB_DCL_EXECUTOR_
|
||||
|
||||
#include "share/ob_define.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
class ObString;
|
||||
}
|
||||
namespace obrpc {
|
||||
class ObCommonRpcProxy;
|
||||
}
|
||||
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObGrantStmt;
|
||||
class ObGrantExecutor {
|
||||
public:
|
||||
ObGrantExecutor()
|
||||
{}
|
||||
virtual ~ObGrantExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObGrantStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObGrantExecutor);
|
||||
};
|
||||
|
||||
class ObRevokeStmt;
|
||||
class ObRevokeExecutor {
|
||||
public:
|
||||
ObRevokeExecutor()
|
||||
{}
|
||||
virtual ~ObRevokeExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObRevokeStmt& stmt);
|
||||
|
||||
private:
|
||||
int revoke_user(obrpc::ObCommonRpcProxy* rpc_proxy, ObRevokeStmt& stmt);
|
||||
int revoke_db(obrpc::ObCommonRpcProxy* rpc_proxy, ObRevokeStmt& stmt);
|
||||
int revoke_table(obrpc::ObCommonRpcProxy* rpc_proxy, ObRevokeStmt& stmt);
|
||||
int revoke_sys_priv(obrpc::ObCommonRpcProxy* rpc_proxy, ObRevokeStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObRevokeExecutor);
|
||||
};
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif // OCEANBASE_SQL_ENGINE_CMD_OB_DCL_EXECUTOR_
|
||||
29
src/sql/engine/cmd/ob_empty_query_executor.cpp
Normal file
29
src/sql/engine/cmd/ob_empty_query_executor.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "sql/engine/cmd/ob_empty_query_executor.h"
|
||||
#include "sql/resolver/cmd/ob_empty_query_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
namespace sql {
|
||||
int ObEmptyQueryExecutor::execute(ObExecContext& ctx, ObEmptyQueryStmt& stmt)
|
||||
{
|
||||
UNUSED(ctx);
|
||||
UNUSED(stmt);
|
||||
int ret = OB_SUCCESS;
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
35
src/sql/engine/cmd/ob_empty_query_executor.h
Normal file
35
src/sql/engine/cmd/ob_empty_query_executor.h
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_ENGINE_EMPTY_QUERY_EXECUTOR_H__
|
||||
#define OCEANBASE_SQL_ENGINE_EMPTY_QUERY_EXECUTOR_H__
|
||||
|
||||
#include "share/ob_define.h"
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObEmptyQueryStmt;
|
||||
|
||||
class ObEmptyQueryExecutor {
|
||||
public:
|
||||
ObEmptyQueryExecutor()
|
||||
{}
|
||||
virtual ~ObEmptyQueryExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObEmptyQueryStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObEmptyQueryExecutor);
|
||||
};
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif /* OCEANBASE_SQL_ENGINE_EMPTY_QUERY_EXECUTOR_H__ */
|
||||
377
src/sql/engine/cmd/ob_index_executor.cpp
Normal file
377
src/sql/engine/cmd/ob_index_executor.cpp
Normal file
@ -0,0 +1,377 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "ob_index_executor.h"
|
||||
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "share/system_variable/ob_system_variable_alias.h"
|
||||
#include "share/schema/ob_table_schema.h"
|
||||
#include "sql/resolver/ddl/ob_create_index_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_drop_index_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_purge_stmt.h"
|
||||
#include "sql/resolver/ob_resolver_utils.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/engine/cmd/ob_partition_executor_utils.h"
|
||||
#include "observer/ob_server.h"
|
||||
|
||||
using namespace oceanbase::common;
|
||||
namespace oceanbase {
|
||||
using namespace oceanbase::share::schema;
|
||||
|
||||
namespace sql {
|
||||
|
||||
ObCreateIndexExecutor::ObCreateIndexExecutor()
|
||||
{}
|
||||
|
||||
ObCreateIndexExecutor::~ObCreateIndexExecutor()
|
||||
{}
|
||||
|
||||
int ObCreateIndexExecutor::execute(ObExecContext& ctx, ObCreateIndexStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
obrpc::ObCreateIndexArg& create_index_arg = stmt.get_create_index_arg();
|
||||
ObSQLSessionInfo* my_session = ctx.get_my_session();
|
||||
const bool is_sys_index = is_inner_table(create_index_arg.index_table_id_);
|
||||
obrpc::ObAlterTableRes res;
|
||||
ObString first_stmt;
|
||||
bool is_sync_ddl_user = false;
|
||||
ObArenaAllocator allocator(ObModIds::OB_SQL_EXECUTOR);
|
||||
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
create_index_arg.ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (NULL == my_session) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to get my session", K(ret), K(ctx));
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_FAIL(ObPartitionExecutorUtils::calc_values_exprs(ctx, stmt))) {
|
||||
LOG_WARN("fail to compare range partition expr", K(ret));
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_INVALID_ID == create_index_arg.session_id_ &&
|
||||
FALSE_IT(create_index_arg.session_id_ = my_session->get_sessid_for_table())) {
|
||||
// impossible
|
||||
} else if (FALSE_IT(create_index_arg.is_inner_ = my_session->is_inner())) {
|
||||
} else if (OB_FAIL(common_rpc_proxy->create_index(create_index_arg, res))) {
|
||||
LOG_WARN("rpc proxy create index failed", K(create_index_arg), "dst", common_rpc_proxy->get_server(), K(ret));
|
||||
} else if (OB_FAIL(ObResolverUtils::check_sync_ddl_user(my_session, is_sync_ddl_user))) {
|
||||
LOG_WARN("Failed to check sync_dll_user", K(ret));
|
||||
} else if (!is_sys_index && !is_sync_ddl_user) {
|
||||
// only check sync index status for non-sys table and when it's not backup or restore
|
||||
create_index_arg.index_schema_.set_table_id(res.index_table_id_);
|
||||
create_index_arg.index_schema_.set_schema_version(res.schema_version_);
|
||||
if (OB_FAIL(sync_check_index_status(*my_session, *common_rpc_proxy, create_index_arg, allocator))) {
|
||||
LOG_WARN("failed to sync_check_index_status", K(create_index_arg), K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateIndexExecutor::set_drop_index_stmt_str(
|
||||
obrpc::ObDropIndexArg& drop_index_arg, common::ObIAllocator& allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
char* buf = NULL;
|
||||
int64_t buf_len = OB_MAX_SQL_LENGTH;
|
||||
int64_t pos = 0;
|
||||
|
||||
if (OB_ISNULL(buf = static_cast<char*>(allocator.alloc(buf_len)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate memory", K(ret), K(OB_MAX_SQL_LENGTH));
|
||||
} else if (is_mysql_mode() && OB_FAIL(databuff_printf(buf,
|
||||
buf_len,
|
||||
pos,
|
||||
"ALTER TABLE `%.*s`.`%.*s` DROP INDEX `%.*s`",
|
||||
drop_index_arg.database_name_.length(),
|
||||
drop_index_arg.database_name_.ptr(),
|
||||
drop_index_arg.table_name_.length(),
|
||||
drop_index_arg.table_name_.ptr(),
|
||||
drop_index_arg.index_name_.length(),
|
||||
drop_index_arg.index_name_.ptr()))) {
|
||||
LOG_WARN("fail to print ddl_stmt_str for rollback", K(ret));
|
||||
} else if (is_oracle_mode() && OB_FAIL(databuff_printf(buf,
|
||||
buf_len,
|
||||
pos,
|
||||
"DROP INDEX \"%.*s\"",
|
||||
drop_index_arg.index_name_.length(),
|
||||
drop_index_arg.index_name_.ptr()))) {
|
||||
LOG_WARN("fail to print ddl_stmt_str for rollback", K(ret));
|
||||
} else {
|
||||
drop_index_arg.ddl_stmt_str_.assign_ptr(buf, static_cast<int32_t>(pos));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// is_update_global_indexes = true: creating index caused by drop/truncate partition,don't need to drop failed index
|
||||
// when reports error. is_update_global_indexes = false:creating index caused by create index/alter table add index,need
|
||||
// to drop failed index when reports error.
|
||||
int ObCreateIndexExecutor::sync_check_index_status(sql::ObSQLSessionInfo& my_session,
|
||||
obrpc::ObCommonRpcProxy& common_rpc_proxy, const obrpc::ObCreateIndexArg& create_index_arg,
|
||||
common::ObIAllocator& allocator, bool is_update_global_indexes)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
// force refresh schema version, make sure version of observer is latest
|
||||
THIS_WORKER.set_timeout_ts(ObTimeUtility::current_time() + OB_MAX_USER_SPECIFIED_TIMEOUT);
|
||||
bool is_finish = false;
|
||||
const static int CHECK_INTERVAL = 100 * 1000; // 100ms
|
||||
obrpc::ObDropIndexArg drop_index_arg;
|
||||
int64_t refreshed_schema_version = OB_INVALID_VERSION;
|
||||
const uint64_t tenant_id = my_session.get_effective_tenant_id();
|
||||
const uint64_t index_table_id = create_index_arg.index_schema_.get_table_id();
|
||||
ObSqlString drop_index_sql;
|
||||
|
||||
if (!is_update_global_indexes) {
|
||||
if (share::is_oracle_mode()) {
|
||||
ret = drop_index_sql.append_fmt(
|
||||
"drop index \"%.*s\"", create_index_arg.index_name_.length(), create_index_arg.index_name_.ptr());
|
||||
} else {
|
||||
ret = drop_index_sql.append_fmt("drop index `%.*s` on `%.*s`",
|
||||
create_index_arg.index_name_.length(),
|
||||
create_index_arg.index_name_.ptr(),
|
||||
create_index_arg.table_name_.length(),
|
||||
create_index_arg.table_name_.ptr());
|
||||
}
|
||||
if (!OB_SUCC(ret)) {
|
||||
OB_LOG(WARN, "fail to append drop index sql", KR(ret));
|
||||
} else {
|
||||
drop_index_arg.tenant_id_ = create_index_arg.tenant_id_;
|
||||
drop_index_arg.exec_tenant_id_ = create_index_arg.tenant_id_;
|
||||
drop_index_arg.index_table_id_ = index_table_id;
|
||||
drop_index_arg.session_id_ = create_index_arg.session_id_;
|
||||
drop_index_arg.index_name_ = create_index_arg.index_name_;
|
||||
drop_index_arg.table_name_ = create_index_arg.table_name_;
|
||||
drop_index_arg.database_name_ = create_index_arg.database_name_;
|
||||
drop_index_arg.index_action_type_ = obrpc::ObIndexArg::DROP_INDEX;
|
||||
drop_index_arg.to_recyclebin_ = false;
|
||||
drop_index_arg.ddl_stmt_str_ = drop_index_sql.string();
|
||||
}
|
||||
}
|
||||
|
||||
while (OB_SUCC(ret) && !is_finish) {
|
||||
// check whether index_table_id received from rs is valid.
|
||||
if (OB_UNLIKELY(OB_INVALID_ID == index_table_id)) {
|
||||
is_finish = true;
|
||||
if (true == create_index_arg.if_not_exist_) {
|
||||
// if not exist, ignore error code and exit check_index_status
|
||||
// since the index is not created, don't need to rollback.
|
||||
break;
|
||||
} else {
|
||||
ret = OB_ERR_ADD_INDEX;
|
||||
LOG_WARN("index table id is invalid", KR(ret), K(index_table_id));
|
||||
}
|
||||
}
|
||||
// handle session timeout or killed first.
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(handle_session_exception(my_session))) {
|
||||
if (!is_update_global_indexes && (OB_ERR_QUERY_INTERRUPTED == ret || OB_SESSION_KILLED == ret)) {
|
||||
LOG_WARN("handle_session_exception", KR(ret));
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
if (OB_SUCCESS != (tmp_ret = common_rpc_proxy.drop_index(drop_index_arg))) {
|
||||
LOG_WARN("rpc proxy drop index failed",
|
||||
"dst",
|
||||
common_rpc_proxy.get_server(),
|
||||
K(tmp_ret),
|
||||
K(drop_index_arg.table_name_),
|
||||
K(drop_index_arg.index_name_));
|
||||
}
|
||||
} else {
|
||||
LOG_WARN("failed to handle_session_exception", KR(ret));
|
||||
}
|
||||
}
|
||||
|
||||
// If switch to standby db when it start to work,
|
||||
// return session killed, and the index is handled by standby.
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_SYS_TENANT_ID == tenant_id) {
|
||||
// no need to process sys tenant
|
||||
} else if (OB_FAIL(handle_switchover())) {
|
||||
if (OB_SESSION_KILLED != ret) {
|
||||
LOG_WARN("fail to handle switchover status", KR(ret));
|
||||
} else {
|
||||
LOG_WARN("fail to add index while swithover", KR(ret));
|
||||
}
|
||||
}
|
||||
|
||||
share::schema::ObMultiVersionSchemaService* schema_service = GCTX.schema_service_;
|
||||
const ObTableSchema* index_schema = NULL;
|
||||
share::schema::ObSchemaGetterGuard schema_guard;
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (NULL == schema_service) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to get schema servicie", KR(ret));
|
||||
} else if (OB_FAIL(schema_service->get_tenant_refreshed_schema_version(tenant_id, refreshed_schema_version))) {
|
||||
LOG_WARN("fail to get tenant refreshed schema version", KR(ret), K(tenant_id), K(refreshed_schema_version));
|
||||
} else if (refreshed_schema_version < create_index_arg.index_schema_.get_schema_version()) {
|
||||
// not refresh schema after the index is created, check again after sleep
|
||||
usleep(CHECK_INTERVAL);
|
||||
LOG_INFO("we have not gotten the index schema",
|
||||
K(index_table_id),
|
||||
K(refreshed_schema_version),
|
||||
K(create_index_arg.index_schema_.get_schema_version()));
|
||||
} else if (OB_FAIL(schema_service->get_tenant_schema_guard(tenant_id, schema_guard))) {
|
||||
LOG_WARN("get schema guard failed", KR(ret), K(refreshed_schema_version));
|
||||
} else if (OB_FAIL(schema_guard.get_table_schema(index_table_id, index_schema))) {
|
||||
LOG_WARN("fail to get index table schema", KR(ret), K(refreshed_schema_version), K(index_table_id));
|
||||
} else if (OB_ISNULL(index_schema)) {
|
||||
// maybe ddl(drop index,drop table,truncate table) in another session has dropped this index.
|
||||
if (!is_update_global_indexes) {
|
||||
ret = OB_ERR_ADD_INDEX;
|
||||
LOG_USER_ERROR(OB_ERR_ADD_INDEX);
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
}
|
||||
LOG_WARN("index table schema is null",
|
||||
KR(ret),
|
||||
K(index_table_id),
|
||||
K(refreshed_schema_version),
|
||||
K(create_index_arg.index_schema_.get_schema_version()));
|
||||
} else if (!is_final_index_status(index_schema->get_index_status(), index_schema->is_dropped_schema())) {
|
||||
usleep(CHECK_INTERVAL);
|
||||
LOG_INFO("index status is not final", K(index_table_id));
|
||||
} else {
|
||||
is_finish = true;
|
||||
LOG_INFO("index status is final", K(index_table_id), K(index_schema->get_index_status()));
|
||||
if (is_error_index_status(index_schema->get_index_status(), index_schema->is_dropped_schema())) {
|
||||
// status of index is ERROR, need to rollback.
|
||||
if (is_update_global_indexes) {
|
||||
ret = OB_ERR_DROP_TRUNCATE_PARTITION_REBUILD_INDEX;
|
||||
LOG_USER_ERROR(OB_ERR_DROP_TRUNCATE_PARTITION_REBUILD_INDEX,
|
||||
create_index_arg.index_name_.length(),
|
||||
create_index_arg.index_name_.ptr());
|
||||
} else {
|
||||
ret = OB_ERR_ADD_INDEX;
|
||||
LOG_USER_ERROR(OB_ERR_ADD_INDEX);
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
if (OB_SUCCESS != (tmp_ret = set_drop_index_stmt_str(drop_index_arg, allocator))) {
|
||||
LOG_WARN("fail to set drop index ddl_stmt_str", K(tmp_ret));
|
||||
} else if (OB_SUCCESS != (tmp_ret = common_rpc_proxy.drop_index(drop_index_arg))) {
|
||||
LOG_WARN("rpc proxy drop index failed",
|
||||
"dst",
|
||||
common_rpc_proxy.get_server(),
|
||||
K(tmp_ret),
|
||||
K(drop_index_arg.table_name_),
|
||||
K(drop_index_arg.index_name_));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateIndexExecutor::handle_session_exception(ObSQLSessionInfo& session)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(session.is_query_killed())) {
|
||||
ret = OB_ERR_QUERY_INTERRUPTED;
|
||||
LOG_WARN("query is killed", K(ret));
|
||||
} else if (OB_UNLIKELY(session.is_zombie())) {
|
||||
ret = OB_SESSION_KILLED;
|
||||
LOG_WARN("session is killed", K(ret));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateIndexExecutor::handle_switchover()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (GCTX.is_standby_cluster()) {
|
||||
ret = OB_SESSION_KILLED;
|
||||
LOG_INFO("create index while switchoverd, kill session", KR(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObDropIndexExecutor::ObDropIndexExecutor()
|
||||
{}
|
||||
|
||||
ObDropIndexExecutor::~ObDropIndexExecutor()
|
||||
{}
|
||||
|
||||
int ObDropIndexExecutor::execute(ObExecContext& ctx, ObDropIndexStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObDropIndexArg& drop_index_arg = stmt.get_drop_index_arg();
|
||||
ObSQLSessionInfo* my_session = ctx.get_my_session();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObDropIndexArg&>(drop_index_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (NULL == my_session) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to get my session", K(ret), K(ctx));
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_INVALID_ID == drop_index_arg.session_id_ &&
|
||||
FALSE_IT(
|
||||
const_cast<obrpc::ObDropIndexArg&>(drop_index_arg).session_id_ = my_session->get_sessid_for_table())) {
|
||||
// impossible
|
||||
} else if (OB_FAIL(common_rpc_proxy->drop_index(drop_index_arg))) {
|
||||
LOG_WARN("rpc proxy drop index failed", "dst", common_rpc_proxy->get_server(), K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPurgeIndexExecutor::execute(ObExecContext& ctx, ObPurgeIndexStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObPurgeIndexArg& purge_index_arg = stmt.get_purge_index_arg();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObPurgeIndexArg&>(purge_index_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->purge_index(purge_index_arg))) {
|
||||
LOG_WARN("rpc proxy purge index failed", "dst", common_rpc_proxy->get_server(), K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
80
src/sql/engine/cmd/ob_index_executor.h
Normal file
80
src/sql/engine/cmd/ob_index_executor.h
Normal file
@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SRC_SQL_ENGINE_CMD_OB_INDEX_EXECUTOR_H_
|
||||
#define OCEANBASE_SRC_SQL_ENGINE_CMD_OB_INDEX_EXECUTOR_H_
|
||||
#include "lib/allocator/ob_allocator.h"
|
||||
namespace oceanbase {
|
||||
namespace obrpc {
|
||||
struct ObCreateIndexArg;
|
||||
struct ObDropIndexArg;
|
||||
class ObCommonRpcProxy;
|
||||
} // namespace obrpc
|
||||
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
|
||||
class ObCreateIndexStmt;
|
||||
class ObSQLSessionInfo;
|
||||
|
||||
class ObCreateIndexExecutor {
|
||||
public:
|
||||
friend class ObAlterTableExecutor;
|
||||
ObCreateIndexExecutor();
|
||||
virtual ~ObCreateIndexExecutor();
|
||||
int execute(ObExecContext& ctx, ObCreateIndexStmt& stmt);
|
||||
|
||||
private:
|
||||
int set_drop_index_stmt_str(obrpc::ObDropIndexArg& drop_index_arg, common::ObIAllocator& allocator);
|
||||
int sync_check_index_status(sql::ObSQLSessionInfo& my_session, obrpc::ObCommonRpcProxy& common_rpc_proxy,
|
||||
const obrpc::ObCreateIndexArg& create_index_arg, common::ObIAllocator& allocator,
|
||||
bool is_update_global_indexes = false);
|
||||
int handle_session_exception(ObSQLSessionInfo& session);
|
||||
int handle_switchover();
|
||||
};
|
||||
|
||||
class ObDropIndexStmt;
|
||||
class ObDropIndexExecutor {
|
||||
public:
|
||||
ObDropIndexExecutor();
|
||||
virtual ~ObDropIndexExecutor();
|
||||
|
||||
int execute(ObExecContext& ctx, ObDropIndexStmt& stmt);
|
||||
};
|
||||
|
||||
class ObFlashBackIndexStmt;
|
||||
class ObFlashBackIndexExecutor {
|
||||
public:
|
||||
ObFlashBackIndexExecutor()
|
||||
{}
|
||||
virtual ~ObFlashBackIndexExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObFlashBackIndexStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObPurgeIndexStmt;
|
||||
class ObPurgeIndexExecutor {
|
||||
public:
|
||||
ObPurgeIndexExecutor()
|
||||
{}
|
||||
virtual ~ObPurgeIndexExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObPurgeIndexStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif /* OCEANBASE_SRC_SQL_ENGINE_CMD_OB_INDEX_EXECUTOR_H_ */
|
||||
248
src/sql/engine/cmd/ob_kill_executor.cpp
Normal file
248
src/sql/engine/cmd/ob_kill_executor.cpp
Normal file
@ -0,0 +1,248 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/resolver/cmd/ob_kill_stmt.h"
|
||||
#include "sql/engine/cmd/ob_kill_executor.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/session/ob_sql_session_mgr.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/engine/cmd/ob_kill_session_arg.h"
|
||||
#include "lib/net/ob_addr.h"
|
||||
#include "lib/string/ob_sql_string.h"
|
||||
#include "lib/mysqlclient/ob_mysql_proxy.h"
|
||||
#include "share/ob_srv_rpc_proxy.h"
|
||||
#include "observer/ob_server_struct.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace obrpc;
|
||||
namespace sql {
|
||||
|
||||
int ObKillExecutor::execute(ObExecContext& ctx, ObKillStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObKillSessionArg arg;
|
||||
ObAddr addr;
|
||||
ObSQLSessionMgr* session_mgr = ctx.get_session_mgr();
|
||||
|
||||
if (OB_ISNULL(session_mgr)) {
|
||||
ret = OB_SUCCESS;
|
||||
LOG_WARN("data member from ObExeccontext is NULL", K(ret), K(session_mgr));
|
||||
} else if (OB_FAIL(arg.init(ctx, stmt))) {
|
||||
LOG_WARN("fail to init kill_session arg", K(ret), K(arg), K(ctx), K(stmt));
|
||||
} else if (OB_FAIL(kill_session(arg, *session_mgr))) {
|
||||
if (OB_ENTRY_NOT_EXIST == ret) { // doesn't find sessid in current server
|
||||
if (OB_FAIL(get_remote_session_location(arg, ctx, addr))) {
|
||||
LOG_WARN("fail to get remote session location", K(ret), K(arg), K(ctx), K(addr));
|
||||
} else if (OB_FAIL(kill_remote_session(ctx, addr, arg))) {
|
||||
LOG_WARN("fail to kill remote session", K(ret), K(ctx), K(addr), K(arg));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
} else {
|
||||
LOG_WARN("fail to kill session", K(ret), K(arg));
|
||||
}
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
|
||||
if (OB_UNKNOWN_CONNECTION == ret) {
|
||||
LOG_USER_ERROR(OB_UNKNOWN_CONNECTION, static_cast<uint64_t>(arg.sess_id_));
|
||||
} else if (OB_ERR_KILL_DENIED == ret) {
|
||||
LOG_USER_ERROR(OB_ERR_KILL_DENIED, static_cast<uint64_t>(arg.sess_id_));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// If you are in system tenant, you can kill all threads and statements in any tenant.
|
||||
// If you have the SUPER privilege, you can kill all threads and statements at your Tenant.
|
||||
// Otherwise, you can kill only your own threads and statements.
|
||||
int ObKillSession::kill_session(const ObKillSessionArg& arg, ObSQLSessionMgr& sess_mgr)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* sess_info = NULL;
|
||||
ObAddr addr;
|
||||
uint32_t sess_id = arg.sess_id_;
|
||||
if (OB_FAIL(get_session(sess_mgr, sess_id, sess_info))) {
|
||||
LOG_WARN("fail to get session", K(ret), K(sess_id));
|
||||
} else if (OB_ISNULL(sess_info)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session info is NULL", K(ret), K(arg));
|
||||
} else if ((OB_SYS_TENANT_ID == arg.tenant_id_) ||
|
||||
((arg.tenant_id_ == sess_info->get_priv_tenant_id()) &&
|
||||
(arg.has_user_super_privilege_ || arg.user_id_ == sess_info->get_user_id()))) {
|
||||
if (arg.is_query_) {
|
||||
if (OB_FAIL(sess_mgr.kill_query(*sess_info))) {
|
||||
LOG_WARN("fail to kill query", K(ret), K(arg));
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(sess_mgr.kill_session(*sess_info))) {
|
||||
LOG_WARN("fail to kill session", K(ret), K(arg));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_KILL_DENIED;
|
||||
}
|
||||
|
||||
if (OB_UNLIKELY(sess_info != NULL && OB_SUCCESS != (tmp_ret = sess_mgr.revert_session(sess_info)))) {
|
||||
// ignore tmp_ret, our monitor will find the error
|
||||
LOG_ERROR("revert session fail", K(tmp_ret), K(arg));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObKillSession::get_session(ObSQLSessionMgr& sess_mgr, uint32_t sess_id, ObSQLSessionInfo*& sess_info)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
sess_info = NULL;
|
||||
ObSQLSessionInfo* sess = NULL;
|
||||
uint32_t version = 0;
|
||||
do {
|
||||
sess = NULL;
|
||||
if (OB_FAIL(sess_mgr.get_session(version, sess_id, sess))) {
|
||||
LOG_WARN("fail to get_session", K(ret), K(version), K(sess_id));
|
||||
} else if (OB_ISNULL(sess)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get session fail", K(ret), K(version), K(sess_id));
|
||||
} else if (OB_UNLIKELY(sess->is_shadow())) {
|
||||
ret = OB_ENTRY_NOT_EXIST;
|
||||
if (OB_UNLIKELY(OB_SUCCESS != (tmp_ret = sess_mgr.revert_session(sess)))) {
|
||||
LOG_ERROR(
|
||||
"fail to revert session", K(sess_id), K(version), "proxy_sessid", sess->get_proxy_sessid(), K(tmp_ret));
|
||||
}
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
++version;
|
||||
} while (OB_UNLIKELY(OB_ENTRY_NOT_EXIST == ret && version <= ObSQLSessionMgr::MAX_VERSION));
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
sess_info = sess;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObKillExecutor::get_remote_session_location(const ObKillSessionArg& arg, ObExecContext& ctx, ObAddr& addr)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res)
|
||||
{
|
||||
ObMySQLProxy* sql_proxy = ctx.get_sql_proxy();
|
||||
sqlclient::ObMySQLResult* result_set = NULL;
|
||||
ObSQLSessionInfo* cur_sess = ctx.get_my_session();
|
||||
ObSqlString read_sql;
|
||||
char svr_ip[OB_IP_STR_BUFF] = "";
|
||||
int64_t svr_port = 0;
|
||||
int64_t tmp_real_str_len = 0;
|
||||
|
||||
// execute sql
|
||||
if (OB_ISNULL(sql_proxy) || OB_ISNULL(cur_sess)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("sql proxy or sesion from exec context is NULL", K(ret), K(sql_proxy), K(cur_sess));
|
||||
} else if (OB_FAIL(generate_read_sql(arg.sess_id_, read_sql))) {
|
||||
LOG_WARN("fail to generate sql", K(ret), K(read_sql), K(*cur_sess), K(arg));
|
||||
} else if (OB_FAIL(sql_proxy->read(res, read_sql.ptr()))) {
|
||||
LOG_WARN("fail to read by sql proxy", K(ret), K(read_sql));
|
||||
} else if (OB_ISNULL(result_set = res.get_result())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("result set is NULL", K(ret), K(read_sql));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
|
||||
// read result_set
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(result_set->next())) {
|
||||
if (OB_LIKELY(OB_ITER_END == ret)) {
|
||||
ret = OB_UNKNOWN_CONNECTION;
|
||||
}
|
||||
LOG_WARN("fail to get next row", K(ret), K(result_set));
|
||||
} else {
|
||||
UNUSED(tmp_real_str_len);
|
||||
EXTRACT_STRBUF_FIELD_MYSQL(*result_set, "svr_ip", svr_ip, OB_IP_STR_BUFF, tmp_real_str_len);
|
||||
EXTRACT_INT_FIELD_MYSQL(*result_set, "svr_port", svr_port, int64_t);
|
||||
}
|
||||
|
||||
// set addr
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_UNLIKELY(OB_ITER_END != result_set->next())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("more than one sessid record", K(ret), K(arg), K(read_sql));
|
||||
} else if (OB_UNLIKELY(!addr.set_ip_addr(svr_ip, static_cast<int32_t>(svr_port)))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to set ip_addr", K(ret), K(svr_ip), K(svr_port));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObKillExecutor::generate_read_sql(uint32_t sess_id, ObSqlString& sql)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const char* sql_str = "select svr_ip, svr_port from oceanbase.__all_virtual_processlist \
|
||||
where id = %u";
|
||||
if (OB_FAIL(sql.append_fmt(sql_str, sess_id))) {
|
||||
LOG_WARN("fail to append sql", K(ret), K(sess_id));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObKillExecutor::kill_remote_session(ObExecContext& ctx, const ObAddr& addr, const ObKillSessionArg& arg)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSrvRpcProxy* rpc_proxy = GCTX.srv_rpc_proxy_;
|
||||
ObSQLSessionInfo* session = ctx.get_my_session();
|
||||
ObPhysicalPlanCtx* plan_ctx = GET_PHY_PLAN_CTX(ctx);
|
||||
if (OB_ISNULL(rpc_proxy) || OB_ISNULL(session) || OB_ISNULL(plan_ctx)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("some params are NULL", K(ret), K(rpc_proxy), K(session), K(plan_ctx));
|
||||
} else {
|
||||
int64_t timeout = plan_ctx->get_timeout_timestamp() - ObTimeUtility::current_time();
|
||||
uint64_t tenant_id = THIS_WORKER.get_rpc_tenant() > 0 ? THIS_WORKER.get_rpc_tenant() : session->get_rpc_tenant_id();
|
||||
if (OB_UNLIKELY(timeout <= 0)) {
|
||||
ret = OB_TIMEOUT;
|
||||
LOG_WARN("task_execute timeout before rpc",
|
||||
K(ret),
|
||||
K(addr),
|
||||
K(timeout),
|
||||
K(arg),
|
||||
K(tenant_id),
|
||||
"timeout_ts",
|
||||
plan_ctx->get_timeout_timestamp());
|
||||
} else if (OB_FAIL(rpc_proxy->to(addr).by(tenant_id).as(OB_SYS_TENANT_ID).timeout(timeout).kill_session(arg))) {
|
||||
LOG_WARN("fail to kill remote session", K(ret), K(addr), K(tenant_id), K(timeout), K(arg));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRpcKillSessionP::process()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObKillSessionArg& arg = arg_;
|
||||
ObSQLSessionMgr* session_mgr = gctx_.session_mgr_;
|
||||
|
||||
if (OB_ISNULL(session_mgr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session mgr from gctx is NULL", K(ret));
|
||||
} else if (OB_FAIL(kill_session(arg, *session_mgr))) {
|
||||
LOG_WARN("fail to kill sessoin", K(ret), K(arg));
|
||||
ret = OB_ENTRY_NOT_EXIST == ret ? OB_UNKNOWN_CONNECTION : ret;
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
79
src/sql/engine/cmd/ob_kill_executor.h
Normal file
79
src/sql/engine/cmd/ob_kill_executor.h
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_ENGINE_CMD_OB_KILL_EXECUTOR_H__
|
||||
#define OCEANBASE_SQL_ENGINE_CMD_OB_KILL_EXECUTOR_H__
|
||||
#include "share/ob_srv_rpc_proxy.h"
|
||||
namespace oceanbase {
|
||||
namespace observer {
|
||||
class ObGlobalContext;
|
||||
}
|
||||
namespace common {
|
||||
class ObSqlString;
|
||||
class ObAddr;
|
||||
} // namespace common
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObKillStmt;
|
||||
class ObSQLSessionInfo;
|
||||
class ObSQLSessionMgr;
|
||||
class ObKillSessionArg;
|
||||
|
||||
class ObKillSession {
|
||||
public:
|
||||
ObKillSession()
|
||||
{}
|
||||
virtual ~ObKillSession()
|
||||
{}
|
||||
|
||||
protected:
|
||||
int kill_session(const ObKillSessionArg& arg, ObSQLSessionMgr& sess_mgr);
|
||||
|
||||
private:
|
||||
int get_session(ObSQLSessionMgr& ses_mgr, uint32_t sessid, ObSQLSessionInfo*& sess_info);
|
||||
DISALLOW_COPY_AND_ASSIGN(ObKillSession);
|
||||
};
|
||||
|
||||
class ObKillExecutor : public ObKillSession {
|
||||
public:
|
||||
ObKillExecutor()
|
||||
{}
|
||||
virtual ~ObKillExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObKillStmt& stmt);
|
||||
|
||||
private:
|
||||
int get_remote_session_location(const ObKillSessionArg& arg, ObExecContext& ctx, common::ObAddr& addr);
|
||||
int generate_read_sql(uint32_t sess_id, common::ObSqlString& sql);
|
||||
int kill_remote_session(ObExecContext& ctx, const common::ObAddr& addr, const ObKillSessionArg& arg);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ObKillExecutor);
|
||||
};
|
||||
|
||||
class ObRpcKillSessionP : public obrpc::ObRpcProcessor<obrpc::ObSrvRpcProxy::ObRpc<obrpc::OB_KILL_SESSION> >,
|
||||
public ObKillSession {
|
||||
public:
|
||||
explicit ObRpcKillSessionP(const observer::ObGlobalContext& gctx) : gctx_(gctx)
|
||||
{}
|
||||
~ObRpcKillSessionP()
|
||||
{}
|
||||
|
||||
protected:
|
||||
int process();
|
||||
|
||||
private:
|
||||
const observer::ObGlobalContext& gctx_;
|
||||
};
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif /* OCEANBASE_SQL_ENGINE_CMD_OB_KILL_EXECUTOR_H__ */
|
||||
//// end of header file
|
||||
113
src/sql/engine/cmd/ob_kill_session_arg.cpp
Normal file
113
src/sql/engine/cmd/ob_kill_session_arg.cpp
Normal file
@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/resolver/cmd/ob_kill_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/code_generator/ob_expr_generator_impl.h"
|
||||
#include "sql/engine/ob_physical_plan.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
namespace sql {
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObKillSessionArg, sess_id_, tenant_id_, user_id_, is_query_, has_user_super_privilege_);
|
||||
|
||||
int ObKillSessionArg::init(ObExecContext& ctx, const ObKillStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
if (OB_ISNULL(session = ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session is NULL", K(ret), K(ctx));
|
||||
} else if (OB_FAIL(calculate_sessid(ctx, stmt))) {
|
||||
LOG_WARN("fail to calculate sessid", K(ret), K(ctx), K(stmt));
|
||||
} else {
|
||||
tenant_id_ = session->get_priv_tenant_id();
|
||||
user_id_ = session->get_user_id();
|
||||
is_query_ = stmt.is_query();
|
||||
has_user_super_privilege_ = session->has_user_super_privilege();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObKillSessionArg::calculate_sessid(ObExecContext& ctx, const ObKillStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* my_session = ctx.get_my_session();
|
||||
ObPhysicalPlanCtx* plan_ctx = ctx.get_physical_plan_ctx();
|
||||
ObPhysicalPlan phy_plan;
|
||||
ObPhysicalPlanCtx phy_plan_ctx(ctx.get_allocator());
|
||||
ObExecContext* exec_ctx = NULL; // because ObExecContext is bigger than 10K, can't use it as local variable
|
||||
ObExprCtx expr_ctx;
|
||||
ObNewRow tmp_row;
|
||||
RowDesc row_desc;
|
||||
ObExprGeneratorImpl expr_gen(0, 0, NULL, row_desc);
|
||||
ObObj value_obj;
|
||||
ObRawExpr* value_expr = NULL;
|
||||
void* tmp_ptr = NULL;
|
||||
if (OB_ISNULL(my_session) || OB_ISNULL(plan_ctx)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("data member from ObExecContext is Null", K(ret), K(my_session), K(plan_ctx));
|
||||
} else {
|
||||
ObArenaAllocator allocator(
|
||||
common::ObModIds::OB_SQL_EXPR_CALC, OB_MALLOC_NORMAL_BLOCK_SIZE, my_session->get_effective_tenant_id());
|
||||
ObSqlExpression sql_expr(allocator, 0);
|
||||
const int64_t cur_time =
|
||||
plan_ctx->has_cur_time() ? plan_ctx->get_cur_time().get_timestamp() : ObTimeUtility::current_time();
|
||||
phy_plan_ctx.set_cur_time(cur_time, *my_session);
|
||||
|
||||
if (OB_UNLIKELY(NULL == (tmp_ptr = allocator.alloc(sizeof(ObExecContext))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_ERROR("fail to alloc ObExecContext", K(ret));
|
||||
} else {
|
||||
exec_ctx = new (tmp_ptr) ObExecContext;
|
||||
phy_plan_ctx.set_phy_plan(&phy_plan);
|
||||
expr_ctx.phy_plan_ctx_ = &phy_plan_ctx;
|
||||
expr_ctx.my_session_ = my_session;
|
||||
expr_ctx.exec_ctx_ = exec_ctx;
|
||||
expr_ctx.calc_buf_ = &allocator;
|
||||
if (OB_ISNULL(value_expr = stmt.get_value_expr())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to get value expr", K(ret), K(value_expr));
|
||||
} else if (OB_FAIL(expr_gen.generate(*value_expr, sql_expr))) {
|
||||
LOG_WARN("fail to fill sql expression", K(ret));
|
||||
} else if (FALSE_IT(phy_plan.set_regexp_op_count(expr_gen.get_cur_regexp_op_count()))) {
|
||||
// will not reach here
|
||||
} else if (FALSE_IT(phy_plan.set_like_op_count(expr_gen.get_cur_like_op_count()))) {
|
||||
// will not reach here
|
||||
} else if (OB_FAIL(sql_expr.calc(expr_ctx, tmp_row, value_obj))) {
|
||||
LOG_WARN("fail to calc value", K(ret), K(stmt.get_value_expr()));
|
||||
} else {
|
||||
const ObObj* res_obj = NULL;
|
||||
EXPR_DEFINE_CAST_CTX(expr_ctx, CM_WARN_ON_FAIL);
|
||||
EXPR_CAST_OBJ_V2(ObUInt32Type, value_obj, res_obj);
|
||||
ret = OB_ERR_TRUNCATED_WRONG_VALUE_FOR_FIELD == ret ? OB_SUCCESS : ret;
|
||||
if (OB_FAIL(ret)) {
|
||||
LOG_WARN(
|
||||
"fail to cast expr", "orig type", value_obj.get_type(), "dest type", "ObUint32type", K(ret), K(res_obj));
|
||||
} else if (OB_ISNULL(res_obj)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN(
|
||||
"fail to cast expr", "orig type", value_obj.get_type(), "dest type", "ObUint32type", K(ret), K(res_obj));
|
||||
} else {
|
||||
sess_id_ = res_obj->get_uint32();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
51
src/sql/engine/cmd/ob_kill_session_arg.h
Normal file
51
src/sql/engine/cmd/ob_kill_session_arg.h
Normal file
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_ENGINE_CMD_OB_KILL_SESSION_ARG_H__
|
||||
#define OCEANBASE_SQL_ENGINE_CMD_OB_KILL_SESSION_ARG_H__
|
||||
|
||||
#include <cstdint>
|
||||
#include "lib/utility/ob_unify_serialize.h"
|
||||
#include "lib/utility/ob_print_utils.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObKillStmt;
|
||||
|
||||
class ObKillSessionArg {
|
||||
OB_UNIS_VERSION(1);
|
||||
|
||||
public:
|
||||
ObKillSessionArg()
|
||||
: sess_id_(0),
|
||||
tenant_id_(common::OB_INVALID_TENANT_ID),
|
||||
user_id_(common::OB_INVALID_ID),
|
||||
is_query_(false),
|
||||
has_user_super_privilege_(false)
|
||||
{}
|
||||
~ObKillSessionArg()
|
||||
{}
|
||||
int init(ObExecContext& ctx, const ObKillStmt& stmt);
|
||||
int calculate_sessid(ObExecContext& ctx, const ObKillStmt& stmt);
|
||||
TO_STRING_KV(K(sess_id_), K(tenant_id_), K(user_id_), K(is_query_), K(has_user_super_privilege_));
|
||||
|
||||
public:
|
||||
uint32_t sess_id_;
|
||||
uint64_t tenant_id_;
|
||||
uint64_t user_id_;
|
||||
bool is_query_;
|
||||
bool has_user_super_privilege_;
|
||||
};
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif
|
||||
43
src/sql/engine/cmd/ob_load_data_executor.cpp
Normal file
43
src/sql/engine/cmd/ob_load_data_executor.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
|
||||
#include "sql/engine/cmd/ob_load_data_executor.h"
|
||||
|
||||
#include "lib/oblog/ob_log_module.h"
|
||||
#include "sql/engine/cmd/ob_load_data_impl.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
int ObLoadDataExecutor::execute(ObExecContext& ctx, ObLoadDataStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObLoadDataBase* load_impl = NULL;
|
||||
if (stmt.get_load_arguments().is_csv_format_
|
||||
? OB_ISNULL(load_impl = OB_NEWx(ObLoadDataSPImpl, (&ctx.get_allocator())))
|
||||
: OB_ISNULL(load_impl = OB_NEWx(ObLoadDataImpl, (&ctx.get_allocator())))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("allocate memory failed", K(ret));
|
||||
} else {
|
||||
if (OB_FAIL(load_impl->execute(ctx, stmt))) {
|
||||
LOG_WARN("failed to execute load data stmt", K(ret));
|
||||
}
|
||||
load_impl->~ObLoadDataBase();
|
||||
ctx.get_allocator().free(load_impl);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
39
src/sql/engine/cmd/ob_load_data_executor.h
Normal file
39
src/sql/engine/cmd/ob_load_data_executor.h
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_LOAD_DATA_EXECUTOR_H_
|
||||
#define OCEANBASE_LOAD_DATA_EXECUTOR_H_
|
||||
#include "sql/resolver/cmd/ob_load_data_stmt.h"
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class ObLoadDataStmt;
|
||||
class ObLoadDataExecutor {
|
||||
public:
|
||||
ObLoadDataExecutor()
|
||||
{}
|
||||
virtual ~ObLoadDataExecutor()
|
||||
{}
|
||||
|
||||
int execute(ObExecContext& ctx, ObLoadDataStmt& stmt);
|
||||
|
||||
private:
|
||||
// disallow copy
|
||||
DISALLOW_COPY_AND_ASSIGN(ObLoadDataExecutor);
|
||||
// function members
|
||||
private:
|
||||
// data members
|
||||
};
|
||||
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
|
||||
#endif /* OCEANBASE_LOAD_DATA_EXECUTOR_H_ */
|
||||
4369
src/sql/engine/cmd/ob_load_data_impl.cpp
Normal file
4369
src/sql/engine/cmd/ob_load_data_impl.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1243
src/sql/engine/cmd/ob_load_data_impl.h
Normal file
1243
src/sql/engine/cmd/ob_load_data_impl.h
Normal file
File diff suppressed because it is too large
Load Diff
705
src/sql/engine/cmd/ob_load_data_rpc.cpp
Normal file
705
src/sql/engine/cmd/ob_load_data_rpc.cpp
Normal file
@ -0,0 +1,705 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
|
||||
#include "sql/engine/cmd/ob_load_data_rpc.h"
|
||||
|
||||
#include "observer/ob_server_struct.h"
|
||||
#include "lib/oblog/ob_log_module.h"
|
||||
#include "lib/string/ob_sql_string.h"
|
||||
#include "lib/utility/serialization.h"
|
||||
#include "share/ob_tenant_mgr.h"
|
||||
#include "storage/ob_partition_service.h"
|
||||
#include "storage/ob_dml_param.h"
|
||||
#include "sql/parser/ob_parser.h"
|
||||
#include "sql/resolver/ob_resolver.h"
|
||||
#include "sql/resolver/dml/ob_insert_stmt.h"
|
||||
#include "sql/plan_cache/ob_sql_parameterization.h"
|
||||
#include "sql/code_generator/ob_expr_generator_impl.h"
|
||||
#include "sql/code_generator/ob_code_generator.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/engine/cmd/ob_load_data_impl.h"
|
||||
|
||||
using namespace oceanbase::sql;
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::share;
|
||||
using namespace oceanbase::share::schema;
|
||||
using namespace oceanbase::storage;
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
|
||||
int ObLoadbuffer::deep_copy_str(const ObString& src, ObString& dest)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
char* buf = NULL;
|
||||
int64_t len = src.length() + 1;
|
||||
if (OB_UNLIKELY(len <= 0)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("src string length is invalid", K(ret), K(src), K(len));
|
||||
} else if (NULL == (buf = static_cast<char*>(field_data_allocator_.alloc(len)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_ERROR("fail to allocate memory, ", K(ret), K(src), K(len));
|
||||
} else {
|
||||
MEMCPY(buf, src.ptr(), len - 1);
|
||||
buf[len - 1] = '\0';
|
||||
dest.assign_ptr(buf, static_cast<ObString::obstr_size_t>(len - 1));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLoadbuffer::store_row(const ObIArray<ObString>& row_strs, int64_t cur_line_number)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < insert_column_num_; ++i) {
|
||||
const ObString& src_str = row_strs.at(i);
|
||||
ObString& dst_str = insert_values_.at(stored_pos_);
|
||||
if (OB_FAIL(deep_copy_str(src_str, dst_str))) {
|
||||
LOG_WARN("deep copy string failed", K(ret));
|
||||
}
|
||||
stored_pos_++;
|
||||
}
|
||||
file_line_number_.at(stored_row_cnt_) = cur_line_number;
|
||||
stored_row_cnt_++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLoadbuffer::set_allocator_tenant()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_INVALID_ID == tenant_id_) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("tenant_id must be init first", K(tenant_id_));
|
||||
} else {
|
||||
field_data_allocator_.set_tenant_id(tenant_id_);
|
||||
array_allocator_.set_tenant_id(tenant_id_);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLoadbuffer::prepare_insert_info(const ObIArray<ObString>& column_names, ObExprValueBitSet& expr_value_bitset)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(expr_bitset_.add_members(expr_value_bitset))) {
|
||||
LOG_WARN("prepare expr bitset failed", K(ret));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < column_names.count(); ++i) {
|
||||
if (OB_FAIL(insert_column_names_.push_back(column_names.at(i)))) {
|
||||
LOG_WARN("insert column names push failed", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLoadbuffer::init_array()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < LOAD_BUFFER_MAX_ROW_COUNT * insert_column_num_; ++i) {
|
||||
if (OB_FAIL(insert_values_.push_back(ObString::make_empty_string()))) {
|
||||
LOG_WARN("insert values push empty string failed", K(ret));
|
||||
}
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < LOAD_BUFFER_MAX_ROW_COUNT; ++i) {
|
||||
if (OB_FAIL(file_line_number_.push_back(-1))) {
|
||||
LOG_WARN("insert values push empty string failed", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRpcLoadDataShuffleTaskExecuteP::process()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObShuffleTask& task = arg_;
|
||||
// ObShuffleResult &result = result_;
|
||||
ObShuffleTaskHandle* handle = nullptr;
|
||||
ObLoadDataStat* job_status = nullptr;
|
||||
|
||||
LOG_DEBUG("LOAD DATA receiving shuffle task", "task_id", task.task_id_);
|
||||
|
||||
if (OB_FAIL(ObGlobalLoadDataStatMap::getInstance()->get_job_status(task.gid_, job_status))) {
|
||||
LOG_WARN("fail to get job, main thread has already quit", K(ret), K(task));
|
||||
} else if (OB_ISNULL(job_status)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("job status is null", K(ret));
|
||||
} else {
|
||||
if (OB_UNLIKELY(THIS_WORKER.is_timeout())) {
|
||||
ret = OB_TIMEOUT;
|
||||
LOG_WARN("LOAD DATA shuffle task timeout", K(ret), K(task));
|
||||
} else if (OB_FAIL(task.shuffle_task_handle_.get_arg(handle))) { // check identifier
|
||||
LOG_ERROR("fail to get arg", K(ret));
|
||||
} else if (OB_FAIL(ObLoadDataSPImpl::exec_shuffle(task.task_id_, handle))) {
|
||||
LOG_WARN("fail to exec shuffle task", K(ret));
|
||||
}
|
||||
handle->result.exec_ret_ = ret;
|
||||
MEM_BARRIER(); // use handle ptr before release job ref
|
||||
job_status->release();
|
||||
}
|
||||
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObRpcLoadDataShuffleTaskCallBack::release_resouce()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int ret1 = complete_task_list_.push_back(handle_);
|
||||
MEM_BARRIER();
|
||||
int ret2 = task_controller_.on_task_finished();
|
||||
if (OB_FAIL(ret1) || OB_FAIL(ret2)) {
|
||||
LOG_ERROR("shuffle call back release resource failed", K(ret1), K(ret2));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRpcLoadDataShuffleTaskCallBack::process()
|
||||
{
|
||||
// int ret = OB_SUCCESS;
|
||||
// ObShuffleResult &result = result_;
|
||||
LOG_DEBUG("LOAD DATA shuffle task callback process");
|
||||
handle_->result.process_us_ = ObTimeUtil::current_time() - get_send_ts();
|
||||
// handle_->result = result;
|
||||
release_resouce();
|
||||
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
void ObRpcLoadDataShuffleTaskCallBack::on_timeout()
|
||||
{
|
||||
LOG_WARN("LOAD DATA main thread shuffle task rpc timeout");
|
||||
if (OB_NOT_NULL(handle_)) {
|
||||
handle_->result.flags_.set_bit(ObTaskResFlag::RPC_TIMEOUT);
|
||||
}
|
||||
release_resouce();
|
||||
}
|
||||
|
||||
void ObRpcLoadDataShuffleTaskCallBack::set_args(const Request& arg)
|
||||
{
|
||||
UNUSED(arg);
|
||||
}
|
||||
|
||||
int ObRpcLoadDataInsertTaskCallBack::release_resouce()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int ret1 = complete_task_list_.push_back(insert_task_);
|
||||
MEM_BARRIER();
|
||||
int ret2 = task_controller_.on_task_finished();
|
||||
if (OB_FAIL(ret1) || OB_FAIL(ret2)) {
|
||||
LOG_ERROR("push back buffer failed", K(ret1), K(ret2));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRpcLoadDataInsertTaskCallBack::process()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
LOG_DEBUG("LOAD DATA insert task callback process");
|
||||
if (OB_NOT_NULL(insert_task_)) {
|
||||
if (OB_FAIL(insert_task_->result_.assign(result_))) {
|
||||
LOG_WARN("fail to assign result", K(ret));
|
||||
} else {
|
||||
insert_task_->result_recv_ts_ = ObTimeUtil::current_time();
|
||||
insert_task_->process_us_ = insert_task_->result_recv_ts_ - get_send_ts();
|
||||
}
|
||||
}
|
||||
release_resouce();
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
void ObRpcLoadDataInsertTaskCallBack::set_args(const Request& arg)
|
||||
{
|
||||
UNUSED(arg);
|
||||
}
|
||||
|
||||
void ObRpcLoadDataInsertTaskCallBack::on_timeout()
|
||||
{
|
||||
int64_t task_id = -2; // undefined
|
||||
if (OB_ISNULL(insert_task_)) {
|
||||
LOG_ERROR("insert task is null on timeout");
|
||||
} else {
|
||||
task_id = insert_task_->task_id_;
|
||||
insert_task_->result_.flags_.set_bit(ObTaskResFlag::RPC_TIMEOUT);
|
||||
}
|
||||
LOG_WARN("LOAD DATA main thread insert task rpc timeout", K(task_id));
|
||||
release_resouce();
|
||||
}
|
||||
|
||||
int ObRpcLoadDataTaskExecuteP::process()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObLoadbuffer& buffer = arg_;
|
||||
ObLoadResult& result = result_;
|
||||
ObIArray<ObString>& column_names = buffer.get_insert_keys();
|
||||
ObIArray<ObString>& values = buffer.get_insert_values();
|
||||
ObString& table_name = buffer.get_table_name();
|
||||
ObExprValueBitSet& expr_bitset = buffer.get_expr_bitset();
|
||||
uint64_t tenant_id = buffer.get_tenant_id();
|
||||
int64_t task_id = buffer.get_task_id();
|
||||
int64_t part_id = buffer.get_part_id();
|
||||
ObLoadDupActionType insert_mode = buffer.get_load_mode();
|
||||
int64_t insert_column_number = column_names.count();
|
||||
int64_t total_values_number = buffer.get_stored_pos(); // values.count() will always be 1000
|
||||
int64_t total_row_number = buffer.get_stored_row_count();
|
||||
int64_t succ_row_count = 0;
|
||||
int need_wait_minor_freeze = false;
|
||||
|
||||
if (OB_UNLIKELY(total_values_number <= 0) || OB_UNLIKELY(insert_column_number <= 0) ||
|
||||
OB_UNLIKELY(total_values_number != insert_column_number * (total_values_number / insert_column_number)) ||
|
||||
OB_UNLIKELY(total_row_number != total_values_number / insert_column_number)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("insert values are invalid",
|
||||
K(ret),
|
||||
K(total_values_number),
|
||||
K(insert_column_number),
|
||||
K(total_row_number),
|
||||
K(buffer));
|
||||
} else if (!escape_data_buffer_.set_data(str_buf_, OB_MAX_DEFAULT_VALUE_LENGTH)) { // for escaped value
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid escape_buf", K(ret));
|
||||
} else {
|
||||
// 1. try insert as one stmt
|
||||
ObSqlString batch_insert_sql;
|
||||
int exec_ret = OB_SUCCESS;
|
||||
int64_t affected_rows = 0;
|
||||
if (OB_FAIL(
|
||||
ObLoadDataUtils::build_insert_sql_string_head(insert_mode, table_name, column_names, batch_insert_sql))) {
|
||||
LOG_WARN("gen insert sql column_names failed", K(ret));
|
||||
} else if (OB_FAIL(ObLoadDataUtils::append_values_in_remote_process(insert_column_number,
|
||||
total_values_number,
|
||||
expr_bitset,
|
||||
values,
|
||||
batch_insert_sql,
|
||||
escape_data_buffer_))) {
|
||||
LOG_WARN("append values failed", K(ret));
|
||||
} else if (OB_UNLIKELY(
|
||||
OB_SUCCESS != (exec_ret = gctx_.sql_proxy_->write(
|
||||
tenant_id, batch_insert_sql.ptr(), affected_rows, get_compatibility_mode())))) {
|
||||
LOG_WARN("fail to execute insert sql in batch",
|
||||
K(exec_ret),
|
||||
K(affected_rows),
|
||||
K(task_id),
|
||||
K(get_compatibility_mode()));
|
||||
} else {
|
||||
// succ!
|
||||
succ_row_count = affected_rows;
|
||||
}
|
||||
|
||||
// 2. if failed, try insert seperately
|
||||
if (OB_SUCC(ret) && OB_SUCCESS != exec_ret) {
|
||||
ObSqlString seperate_insert_sql_head;
|
||||
ObSqlString seperate_insert_sql;
|
||||
|
||||
if (OB_FAIL(ObLoadDataUtils::build_insert_sql_string_head(
|
||||
insert_mode, table_name, column_names, seperate_insert_sql_head))) {
|
||||
LOG_WARN("gen insert sql column_names failed", K(ret));
|
||||
}
|
||||
for (int64_t row_idx = 0; OB_SUCC(ret) && row_idx < total_row_number; ++row_idx) {
|
||||
if (OB_FAIL(seperate_insert_sql.assign(seperate_insert_sql_head.string()))) {
|
||||
LOG_WARN("assign insert column_names failed", K(ret));
|
||||
} else if (OB_FAIL(ObLoadDataUtils::append_values_in_remote_process(insert_column_number,
|
||||
insert_column_number,
|
||||
expr_bitset,
|
||||
values,
|
||||
seperate_insert_sql,
|
||||
escape_data_buffer_,
|
||||
row_idx))) {
|
||||
LOG_WARN("append values failed", K(ret));
|
||||
} else {
|
||||
exec_ret = OB_SUCCESS;
|
||||
affected_rows = 0;
|
||||
if (OB_UNLIKELY(
|
||||
OB_SUCCESS != (exec_ret = gctx_.sql_proxy_->write(
|
||||
tenant_id, seperate_insert_sql.ptr(), affected_rows, get_compatibility_mode())))) {
|
||||
LOG_WARN("LOAD DATA row insert failed in remote process",
|
||||
K(exec_ret),
|
||||
K(seperate_insert_sql),
|
||||
K(get_compatibility_mode()));
|
||||
if (OB_FAIL(result.row_number_.push_back(static_cast<int16_t>(row_idx)))) {
|
||||
LOG_WARN("push back row number failed", K(ret));
|
||||
} else if (OB_FAIL(result.row_err_code_.push_back(exec_ret))) {
|
||||
LOG_WARN("push back row err code failed", K(ret));
|
||||
}
|
||||
} else {
|
||||
// succ!
|
||||
succ_row_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// check memory
|
||||
int memory_check_ret = OB_SUCCESS;
|
||||
ObTenantManager& tenant_mgr = ObTenantManager::get_instance();
|
||||
if (OB_UNLIKELY(!tenant_mgr.has_tenant(tenant_id))) {
|
||||
memory_check_ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("tenant no found", K(tenant_id), K(memory_check_ret));
|
||||
} else {
|
||||
int64_t active_memstore_used = 0;
|
||||
int64_t total_memstore_used = 0;
|
||||
int64_t major_freeze_trigger = 0;
|
||||
int64_t memstore_limit = 0;
|
||||
int64_t freeze_cnt = 0;
|
||||
if (OB_UNLIKELY(OB_SUCCESS != (memory_check_ret = tenant_mgr.get_tenant_memstore_cond(tenant_id,
|
||||
active_memstore_used,
|
||||
total_memstore_used,
|
||||
major_freeze_trigger,
|
||||
memstore_limit,
|
||||
freeze_cnt)))) {
|
||||
LOG_WARN("fail to get memstore used", K(memory_check_ret));
|
||||
} else {
|
||||
if (static_cast<double>(total_memstore_used) > static_cast<double>(major_freeze_trigger) * 1.02) {
|
||||
need_wait_minor_freeze = true;
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("load data check tenant memory usage",
|
||||
K(active_memstore_used),
|
||||
K(total_memstore_used),
|
||||
K(major_freeze_trigger),
|
||||
K(memstore_limit),
|
||||
K(freeze_cnt));
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_SUCCESS != memory_check_ret) {
|
||||
ret = memory_check_ret; // cover ret
|
||||
}
|
||||
// sumarize return value
|
||||
if (OB_FAIL(ret)) {
|
||||
ObLoadDataUtils::set_flag(result.task_flags_, static_cast<int64_t>(ObLoadTaskResultFlag::RPC_REMOTE_PROCESS_ERROR));
|
||||
}
|
||||
if (need_wait_minor_freeze) {
|
||||
ObLoadDataUtils::set_flag(result.task_flags_, static_cast<int64_t>(ObLoadTaskResultFlag::NEED_WAIT_MINOR_FREEZE));
|
||||
}
|
||||
if (succ_row_count != total_row_number) {
|
||||
ObLoadDataUtils::set_flag(result.task_flags_, static_cast<int64_t>(ObLoadTaskResultFlag::HAS_FAILED_ROW));
|
||||
}
|
||||
if (succ_row_count == 0) {
|
||||
ObLoadDataUtils::set_flag(result.task_flags_, static_cast<int64_t>(ObLoadTaskResultFlag::ALL_ROWS_FAILED));
|
||||
}
|
||||
result.affected_rows_ = succ_row_count;
|
||||
result.failed_rows_ = total_row_number - succ_row_count;
|
||||
result.task_id_ = task_id;
|
||||
result.part_id_ = part_id;
|
||||
LOG_DEBUG("load data in remote process!",
|
||||
K(task_id),
|
||||
K(succ_row_count),
|
||||
K(total_row_number),
|
||||
K(need_wait_minor_freeze),
|
||||
K(share::is_oracle_mode()));
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
OB_INLINE void ObRpcLoadDataTaskCallBack::set_args(const Request& arg)
|
||||
{
|
||||
UNUSED(arg);
|
||||
}
|
||||
|
||||
void ObRpcLoadDataTaskCallBack::on_timeout()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObLoadbuffer* buffer = static_cast<ObLoadbuffer*>(request_buffer_ptr_);
|
||||
if (OB_ISNULL(buffer)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("buffer is null", K(ret));
|
||||
} else {
|
||||
buffer->set_returned_timestamp(ObTimeUtility::current_time());
|
||||
ObLoadDataUtils::set_flag(buffer->get_task_status(), static_cast<int64_t>(ObLoadTaskResultFlag::TIMEOUT));
|
||||
ObLoadDataUtils::set_flag(buffer->get_task_status(), static_cast<int64_t>(ObLoadTaskResultFlag::HAS_FAILED_ROW));
|
||||
ObLoadDataUtils::set_flag(buffer->get_task_status(), static_cast<int64_t>(ObLoadTaskResultFlag::ALL_ROWS_FAILED));
|
||||
// TODO: check task real status, is all rows truely failed?
|
||||
if (OB_FAIL(complete_task_list_.push_back(buffer))) {
|
||||
LOG_ERROR("push back buffer failed", K(ret));
|
||||
}
|
||||
MEM_BARRIER();
|
||||
if (OB_FAIL(task_controller_.on_task_finished())) {
|
||||
LOG_ERROR("error on task finish", K(ret));
|
||||
}
|
||||
LOG_WARN("load data task is timeout", K(ret), KPC(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
int ObRpcLoadDataTaskCallBack::process()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObLoadResult& result = result_;
|
||||
ObLoadbuffer* buffer = static_cast<ObLoadbuffer*>(request_buffer_ptr_);
|
||||
if (OB_ISNULL(buffer)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("task buffer is null", K(ret));
|
||||
} else {
|
||||
buffer->set_returned_timestamp(ObTimeUtility::current_time());
|
||||
buffer->set_task_status(result.task_flags_);
|
||||
if (OB_UNLIKELY(ObLoadDataUtils::has_flag(
|
||||
buffer->get_task_status(), static_cast<int64_t>(ObLoadTaskResultFlag::HAS_FAILED_ROW)))) {
|
||||
if (OB_UNLIKELY(result.failed_rows_ != result.row_err_code_.count() ||
|
||||
result.failed_rows_ != result.row_number_.count())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("size of failed rows is not the same, impossible");
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < result.failed_rows_; ++i) {
|
||||
if (OB_FAIL(buffer->get_failed_row_idx().push_back(result.row_number_.at(i)))) {
|
||||
LOG_WARN("push back failed", K(ret));
|
||||
} else if (OB_FAIL(buffer->get_error_code_array().push_back(result.row_err_code_.at(i)))) {
|
||||
LOG_WARN("push back failed", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
ObLoadDataUtils::set_flag(
|
||||
buffer->get_task_status(), static_cast<int64_t>(ObLoadTaskResultFlag::RPC_CALLBACK_PROCESS_ERROR));
|
||||
}
|
||||
|
||||
// whatever ret is, the task has finished
|
||||
int second_ret = OB_SUCCESS;
|
||||
if (OB_SUCCESS != (second_ret = complete_task_list_.push_back(buffer))) {
|
||||
// buffer will be auto released by the allocator
|
||||
if (OB_SUCCESS == ret) {
|
||||
ret = second_ret;
|
||||
}
|
||||
LOG_ERROR("push to complete list failed", K(second_ret));
|
||||
}
|
||||
MEM_BARRIER();
|
||||
if (OB_SUCCESS != (second_ret = task_controller_.on_task_finished())) {
|
||||
// signal main thread failed, fetal error. TODO: handle this error
|
||||
if (OB_SUCCESS == ret) {
|
||||
ret = second_ret;
|
||||
}
|
||||
LOG_ERROR("on task finished failed", K(ret));
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("in local cb process!", K(result), K(ret));
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObParallelTaskController::init(int64_t max_parallelism)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
max_parallelism_ = max_parallelism;
|
||||
if (OB_FAIL(vacant_cond_.init(common::ObWaitEventIds::ASYNC_RPC_PROXY_COND_WAIT))) {
|
||||
LOG_WARN("init vacant cond failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObParallelTaskController::on_next_task()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObThreadCondGuard guard(vacant_cond_);
|
||||
|
||||
if (ATOMIC_AAF(&processing_cnt_, 1) > max_parallelism_) {
|
||||
ret = vacant_cond_.wait();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ObParallelTaskController::wait_all_task_finish(const char* task_name, int64_t until_ts)
|
||||
{
|
||||
int64_t wait_duration_ms = 0;
|
||||
int64_t begin_ts = ObTimeUtil::current_time();
|
||||
int64_t processing_count = 0;
|
||||
bool is_too_long = false;
|
||||
LOG_DEBUG("start wait_all_task_finish", K(task_name));
|
||||
while ((processing_count = get_processing_task_cnt()) > 0) {
|
||||
usleep(1000 * 10); // wait 10m
|
||||
wait_duration_ms += 10;
|
||||
if (0 == wait_duration_ms % 1000) {
|
||||
int64_t current_ts = ObTimeUtil::current_time();
|
||||
if (current_ts > until_ts) {
|
||||
LOG_ERROR("waiting load data task too long and exceed max waiting timestamp",
|
||||
K(begin_ts),
|
||||
K(until_ts),
|
||||
K(current_ts));
|
||||
}
|
||||
}
|
||||
if (!is_too_long && wait_duration_ms > 10 * 1000) {
|
||||
is_too_long = true;
|
||||
LOG_WARN("LOAD DATA, waiting task finish too long",
|
||||
K(task_name),
|
||||
K(processing_count),
|
||||
K(wait_duration_ms),
|
||||
K(until_ts));
|
||||
}
|
||||
}
|
||||
if (is_too_long) {
|
||||
LOG_WARN("LOAD DATA finish waitting long task", K(wait_duration_ms));
|
||||
}
|
||||
}
|
||||
|
||||
int ObParallelTaskController::on_task_finished()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (max_parallelism_ == ATOMIC_AAF(&processing_cnt_, -1)) {
|
||||
ObThreadCondGuard guard(vacant_cond_);
|
||||
ret = vacant_cond_.signal();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRpcLoadDataInsertTaskExecuteP::process()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObInsertTask& task = arg_;
|
||||
ObInsertResult& result = result_;
|
||||
|
||||
LOG_DEBUG("LOAD DATA receiving insert task", "task_id", task.task_id_);
|
||||
|
||||
bool need_wait_freeze = false;
|
||||
|
||||
if (OB_UNLIKELY(THIS_WORKER.is_timeout())) {
|
||||
ret = OB_TIMEOUT;
|
||||
LOG_WARN("LOAD DATA shuffle task timeout", K(ret), K(task));
|
||||
} else if (OB_FAIL(ObLoadDataSPImpl::exec_insert(task, result))) {
|
||||
LOG_WARN("fail to exec insert", K(ret));
|
||||
}
|
||||
|
||||
result.exec_ret_ = ret;
|
||||
|
||||
int temp_ret = ObLoadDataBase::memory_check_remote(task.tenant_id_, need_wait_freeze);
|
||||
if (OB_SUCCESS != temp_ret) {
|
||||
LOG_WARN("LOAD DATA remote memory check failed", K(temp_ret), K(task.tenant_id_));
|
||||
}
|
||||
|
||||
result.flags_.reset();
|
||||
if (need_wait_freeze) {
|
||||
result.flags_.set_bit(ObTaskResFlag::NEED_WAIT_MINOR_FREEZE);
|
||||
}
|
||||
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
int ObInsertResult::assign(const ObInsertResult& other)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
flags_ = other.flags_;
|
||||
exec_ret_ = other.exec_ret_;
|
||||
if (OB_FAIL(failed_row_offset_.add_members(other.failed_row_offset_))) {
|
||||
LOG_WARN("fail to add members", K(ret));
|
||||
} else if (OB_FAIL(row_errors_.assign(other.row_errors_))) {
|
||||
LOG_WARN("fail to assign error rows", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE(ObLoadbuffer)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
LST_DO_CODE(OB_UNIS_ENCODE,
|
||||
task_id_,
|
||||
part_id_,
|
||||
table_id_,
|
||||
tenant_id_,
|
||||
stored_pos_,
|
||||
stored_row_cnt_,
|
||||
insert_mode_,
|
||||
insert_column_num_);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(table_name_.serialize(buf, buf_len, pos))) {
|
||||
LOG_WARN("serialize error", K(ret));
|
||||
} else if (OB_FAIL(insert_column_names_.serialize(buf, buf_len, pos))) {
|
||||
LOG_WARN("serialize column names error", K(ret));
|
||||
} else if (OB_FAIL(insert_values_.serialize(buf, buf_len, pos))) {
|
||||
LOG_WARN("serialize row store error", K(ret));
|
||||
} else if (OB_FAIL(expr_bitset_.serialize(buf, buf_len, pos))) {
|
||||
LOG_WARN("serialize expr bitset error", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_DESERIALIZE(ObLoadbuffer)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
LST_DO_CODE(OB_UNIS_DECODE,
|
||||
task_id_,
|
||||
part_id_,
|
||||
table_id_,
|
||||
tenant_id_,
|
||||
stored_pos_,
|
||||
stored_row_cnt_,
|
||||
insert_mode_,
|
||||
insert_column_num_);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(table_name_.deserialize(buf, data_len, pos))) {
|
||||
LOG_WARN("deserialize error", K(ret));
|
||||
} else if (OB_FAIL(insert_column_names_.deserialize(buf, data_len, pos))) {
|
||||
LOG_WARN("deserialize row store error", K(ret));
|
||||
} else if (OB_FAIL(insert_values_.deserialize(buf, data_len, pos))) {
|
||||
LOG_WARN("deserialize row store error", K(ret));
|
||||
} else if (OB_FAIL(expr_bitset_.deserialize(buf, data_len, pos))) {
|
||||
LOG_WARN("deserialize expr bitset error", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE_SIZE(ObLoadbuffer)
|
||||
{
|
||||
int64_t len = 0;
|
||||
LST_DO_CODE(OB_UNIS_ADD_LEN,
|
||||
task_id_,
|
||||
part_id_,
|
||||
table_id_,
|
||||
tenant_id_,
|
||||
stored_pos_,
|
||||
stored_row_cnt_,
|
||||
insert_mode_,
|
||||
insert_column_num_);
|
||||
len += table_name_.get_serialize_size();
|
||||
len += insert_column_names_.get_serialize_size();
|
||||
len += insert_values_.get_serialize_size();
|
||||
len += expr_bitset_.get_serialize_size();
|
||||
return len;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE(ObLoadResult)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
LST_DO_CODE(OB_UNIS_ENCODE, task_id_, part_id_, affected_rows_, failed_rows_, task_flags_);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(row_number_.serialize(buf, buf_len, pos))) {
|
||||
LOG_WARN("serialize row_number_ error", K(ret));
|
||||
} else if (OB_FAIL(row_err_code_.serialize(buf, buf_len, pos))) {
|
||||
LOG_WARN("serialize row_err_code_ error", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_DESERIALIZE(ObLoadResult)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
LST_DO_CODE(OB_UNIS_DECODE, task_id_, part_id_, affected_rows_, failed_rows_, task_flags_);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(row_number_.deserialize(buf, data_len, pos))) {
|
||||
LOG_WARN("deserialize row_number_ error", K(ret));
|
||||
} else if (OB_FAIL(row_err_code_.deserialize(buf, data_len, pos))) {
|
||||
LOG_WARN("deserialize row_err_code_ error", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE_SIZE(ObLoadResult)
|
||||
{
|
||||
int64_t len = 0;
|
||||
LST_DO_CODE(OB_UNIS_ADD_LEN, task_id_, part_id_, affected_rows_, failed_rows_, task_flags_);
|
||||
len += row_number_.get_serialize_size();
|
||||
len += row_err_code_.get_serialize_size();
|
||||
return len;
|
||||
}
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObShuffleTask, task_id_, shuffle_task_handle_, gid_);
|
||||
OB_SERIALIZE_MEMBER(ObShuffleResult, task_id_, flags_, exec_ret_, row_cnt_);
|
||||
|
||||
OB_SERIALIZE_MEMBER(
|
||||
ObInsertTask, tenant_id_, task_id_, row_count_, column_count_, insert_stmt_head_, insert_value_data_);
|
||||
OB_SERIALIZE_MEMBER(ObInsertResult, flags_, exec_ret_, failed_row_offset_, row_errors_);
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
681
src/sql/engine/cmd/ob_load_data_rpc.h
Normal file
681
src/sql/engine/cmd/ob_load_data_rpc.h
Normal file
@ -0,0 +1,681 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_ENGINE_CMD_LOAD_DATA_RPC_H_
|
||||
#define OCEANBASE_SQL_ENGINE_CMD_LOAD_DATA_RPC_H_
|
||||
|
||||
#include "share/ob_define.h"
|
||||
#include "rpc/obrpc/ob_rpc_proxy.h"
|
||||
#include "rpc/obrpc/ob_rpc_processor.h"
|
||||
#include "lib/container/ob_bit_set.h"
|
||||
#include "lib/lock/ob_thread_cond.h"
|
||||
#include "sql/ob_sql_utils.h"
|
||||
#include "sql/engine/cmd/ob_load_data_utils.h"
|
||||
#include "share/config/ob_server_config.h"
|
||||
#include "observer/ob_server_struct.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace observer {
|
||||
class ObGlobalContext;
|
||||
}
|
||||
|
||||
namespace sql {
|
||||
class ObLoadbuffer;
|
||||
class ObLoadResult;
|
||||
class ObLoadFileBuffer;
|
||||
class ObDesExecContext;
|
||||
class ObShuffleTask;
|
||||
class ObShuffleResult;
|
||||
class ObInsertTask;
|
||||
class ObInsertResult;
|
||||
class ObDataFragMgr;
|
||||
class ObDataFrag;
|
||||
class ObShuffleTaskHandle;
|
||||
class ObInsertValueGenerator;
|
||||
class ObPartIdCalculator;
|
||||
class ObPartDataFragMgr;
|
||||
} // namespace sql
|
||||
|
||||
namespace obrpc {
|
||||
class ObLoadDataRpcProxy : public obrpc::ObRpcProxy {
|
||||
public:
|
||||
DEFINE_TO(ObLoadDataRpcProxy);
|
||||
RPC_AP(@PR5 ap_load_data_execute, obrpc::OB_LOAD_DATA_EXECUTE, (sql::ObLoadbuffer), sql::ObLoadResult);
|
||||
RPC_AP(@PR5 ap_load_data_shuffle, obrpc::OB_LOAD_DATA_SHUFFLE, (sql::ObShuffleTask), sql::ObShuffleResult);
|
||||
RPC_AP(@PR5 ap_load_data_insert, obrpc::OB_LOAD_DATA_INSERT, (sql::ObInsertTask), sql::ObInsertResult);
|
||||
};
|
||||
} // namespace obrpc
|
||||
|
||||
namespace sql {
|
||||
|
||||
static const int64_t DEFAULT_BUFFERRED_ROW_COUNT = 1000; // must < 2^15
|
||||
static const int64_t DEFAULT_PARALLEL_THREAD_COUNT = 4;
|
||||
static const int64_t EXPECTED_INSERT_COLUMN_NUM = 64;
|
||||
static const int64_t RPC_BATCH_INSERT_TIMEOUT_US = 10 * 1000 * 1000; // 10s
|
||||
|
||||
enum class ObLoadTaskResultFlag {
|
||||
HAS_FAILED_ROW = 0,
|
||||
ALL_ROWS_FAILED,
|
||||
NEED_WAIT_MINOR_FREEZE,
|
||||
TIMEOUT,
|
||||
RPC_CALLBACK_PROCESS_ERROR,
|
||||
RPC_REMOTE_PROCESS_ERROR,
|
||||
INVALID_MAX_FLAG
|
||||
};
|
||||
|
||||
static_assert(static_cast<int64_t>(ObLoadTaskResultFlag::INVALID_MAX_FLAG) < 64,
|
||||
"ObLoadTaskResultFlag max value should less than 64");
|
||||
|
||||
enum class ObTaskResFlag {
|
||||
RPC_TIMEOUT = 0,
|
||||
NEED_WAIT_MINOR_FREEZE,
|
||||
HAS_FAILED_ROW,
|
||||
ALL_ROW_FAILED,
|
||||
// SHUTDOWN_WITH_INTERNAL_ERROR,
|
||||
|
||||
MAX_VALUE
|
||||
};
|
||||
|
||||
typedef ObBitSet<32> ErrRowBitset;
|
||||
|
||||
class ObParallelTaskController {
|
||||
public:
|
||||
ObParallelTaskController() : max_parallelism_(0), task_cnt_(0), processing_cnt_(0)
|
||||
{}
|
||||
~ObParallelTaskController()
|
||||
{}
|
||||
int init(int64_t max_parallelism);
|
||||
int on_next_task();
|
||||
int on_task_finished();
|
||||
int64_t get_next_task_id()
|
||||
{
|
||||
return task_cnt_++;
|
||||
}
|
||||
void wait_all_task_finish(const char* task_name = NULL, int64_t until_ts = INT64_MAX);
|
||||
int64_t get_processing_task_cnt()
|
||||
{
|
||||
return ATOMIC_LOAD(&processing_cnt_);
|
||||
}
|
||||
int64_t get_total_task_cnt()
|
||||
{
|
||||
return task_cnt_;
|
||||
}
|
||||
int64_t get_max_parallelism()
|
||||
{
|
||||
return max_parallelism_;
|
||||
}
|
||||
|
||||
private:
|
||||
static const int64_t MAX_TIME_WAIT_MS = 2 * RPC_BATCH_INSERT_TIMEOUT_US / 1000;
|
||||
int64_t max_parallelism_;
|
||||
int64_t task_cnt_;
|
||||
|
||||
// multi-thread values:
|
||||
volatile int64_t processing_cnt_;
|
||||
common::ObThreadCond vacant_cond_; // wait on (processing_cnt_ > MaxConcurrentTaskNum)
|
||||
};
|
||||
|
||||
struct ObInsertResult {
|
||||
ObInsertResult() : exec_ret_(0)
|
||||
{}
|
||||
void reset()
|
||||
{
|
||||
flags_.reset();
|
||||
exec_ret_ = 0;
|
||||
}
|
||||
int assign(const ObInsertResult& other);
|
||||
ObEnumBitSet<ObTaskResFlag> flags_;
|
||||
int exec_ret_;
|
||||
ErrRowBitset failed_row_offset_;
|
||||
common::Ob2DArray<int> row_errors_;
|
||||
TO_STRING_KV(K(exec_ret_), K(flags_));
|
||||
OB_UNIS_VERSION(1);
|
||||
};
|
||||
|
||||
struct ObInsertTask {
|
||||
static constexpr int64_t RETRY_LIMIT = 3;
|
||||
static constexpr int64_t COMMON_SIZE = 10;
|
||||
|
||||
ObInsertTask()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
void reuse()
|
||||
{
|
||||
task_id_ = common::OB_INVALID_ID;
|
||||
row_count_ = 0;
|
||||
insert_value_data_.reuse();
|
||||
source_frag_.reuse();
|
||||
result_.reset();
|
||||
result_recv_ts_ = 0;
|
||||
process_us_ = 0;
|
||||
retry_times_ = 0;
|
||||
part_mgr = NULL;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
tenant_id_ = common::OB_INVALID_TENANT_ID;
|
||||
column_count_ = 0;
|
||||
reuse();
|
||||
token_server_idx_ = OB_INVALID_INDEX;
|
||||
non_string_fields_.reset();
|
||||
insert_stmt_head_.reset();
|
||||
insert_value_data_.reset();
|
||||
source_frag_.reset();
|
||||
}
|
||||
|
||||
bool is_empty_task()
|
||||
{
|
||||
return task_id_ == OB_INVALID_ID;
|
||||
}
|
||||
|
||||
TO_STRING_KV(K(tenant_id_), K(task_id_), K(row_count_), K(column_count_), K(insert_value_data_.count()));
|
||||
|
||||
// serialized data:
|
||||
uint64_t tenant_id_;
|
||||
int64_t task_id_;
|
||||
int64_t row_count_;
|
||||
int64_t column_count_;
|
||||
ObBitSet<> non_string_fields_;
|
||||
common::ObString insert_stmt_head_; // insert into xxx (xxx)
|
||||
|
||||
// serialized format:
|
||||
// 1. length of 2 int64_t
|
||||
// 2. values for one row ObSEArray<ObString> using string as buf
|
||||
// + for serialize
|
||||
common::ObSEArray<common::ObString, COMMON_SIZE> insert_value_data_;
|
||||
|
||||
// no serialized data
|
||||
common::ObSEArray<void*, COMMON_SIZE> source_frag_;
|
||||
ObPartDataFragMgr* part_mgr;
|
||||
ObInsertResult result_;
|
||||
int64_t result_recv_ts_;
|
||||
int64_t process_us_;
|
||||
int64_t retry_times_;
|
||||
int64_t token_server_idx_;
|
||||
|
||||
OB_UNIS_VERSION(1);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class ObRpcPointerArg {
|
||||
public:
|
||||
ObRpcPointerArg() : ptr_value_(0)
|
||||
{}
|
||||
int set_arg(T* ptr)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(ptr)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
} else {
|
||||
ptr_ = ptr;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int get_arg(T*& ptr)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(ptr = ptr_)) {
|
||||
ret = OB_ERR_NULL_VALUE;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
union {
|
||||
uint64_t ptr_value_;
|
||||
T* ptr_;
|
||||
};
|
||||
OB_UNIS_VERSION(1);
|
||||
};
|
||||
|
||||
OB_SERIALIZE_MEMBER_TEMP(template <class T>, ObRpcPointerArg<T>, ptr_value_);
|
||||
|
||||
struct ObShuffleTask {
|
||||
ObShuffleTask() : task_id_(OB_INVALID_INDEX_INT64)
|
||||
{}
|
||||
int64_t task_id_;
|
||||
ObRpcPointerArg<ObShuffleTaskHandle> shuffle_task_handle_;
|
||||
ObLoadDataGID gid_;
|
||||
TO_STRING_KV(K(task_id_), K(gid_));
|
||||
OB_UNIS_VERSION(1);
|
||||
};
|
||||
|
||||
struct ObShuffleResult {
|
||||
ObShuffleResult() : task_id_(OB_INVALID_INDEX_INT64), flags_(), exec_ret_(0), row_cnt_(0), process_us_(0)
|
||||
{}
|
||||
void reset()
|
||||
{
|
||||
task_id_ = OB_INVALID_INDEX_INT64;
|
||||
flags_.reset();
|
||||
exec_ret_ = 0;
|
||||
row_cnt_ = 0;
|
||||
process_us_ = 0;
|
||||
}
|
||||
int64_t task_id_;
|
||||
ObEnumBitSet<ObTaskResFlag> flags_;
|
||||
int exec_ret_;
|
||||
int64_t row_cnt_;
|
||||
int64_t process_us_;
|
||||
OB_UNIS_VERSION(1);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ObConcurrentFixedCircularArray {
|
||||
public:
|
||||
ObConcurrentFixedCircularArray() : array_size_(0), data_(NULL), head_pos_(0), tail_pos_(0)
|
||||
{}
|
||||
~ObConcurrentFixedCircularArray()
|
||||
{
|
||||
if (data_ != NULL) {
|
||||
ob_free_align(static_cast<void*>(data_));
|
||||
}
|
||||
}
|
||||
int init(int64_t array_size)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (OB_ISNULL(data_ = static_cast<T*>(
|
||||
ob_malloc_align(CACHE_ALIGN_SIZE, array_size * sizeof(T), common::ObModIds::OB_SQL_EXECUTOR)))) {
|
||||
ret = common::OB_ALLOCATE_MEMORY_FAILED;
|
||||
LIB_LOG(WARN, "alloc memory failed", K(ret));
|
||||
} else {
|
||||
array_size_ = array_size;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
OB_INLINE int push_back(const T& obj)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
// push optimistically
|
||||
int64_t pos = ATOMIC_FAA(&head_pos_, 1);
|
||||
// validate
|
||||
if (OB_UNLIKELY(pos - ATOMIC_LOAD(&tail_pos_) >= array_size_)) {
|
||||
ret = common::OB_SIZE_OVERFLOW;
|
||||
} else {
|
||||
ATOMIC_SET(&data_[pos % array_size_], obj);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
OB_INLINE int pop(T& output)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
// pop optimistically
|
||||
int64_t pos = ATOMIC_FAA(&tail_pos_, 1);
|
||||
// validate
|
||||
if (OB_UNLIKELY(pos >= ATOMIC_LOAD(&head_pos_))) {
|
||||
ret = common::OB_ARRAY_OUT_OF_RANGE;
|
||||
} else {
|
||||
output = ATOMIC_LOAD(&data_[pos % array_size_]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
OB_INLINE int64_t count()
|
||||
{
|
||||
return ATOMIC_LOAD(&head_pos_) - ATOMIC_LOAD(&tail_pos_);
|
||||
}
|
||||
|
||||
private:
|
||||
// data members
|
||||
int64_t array_size_;
|
||||
T* volatile data_;
|
||||
volatile int64_t head_pos_;
|
||||
volatile int64_t tail_pos_;
|
||||
};
|
||||
|
||||
typedef ObConcurrentFixedCircularArray<ObLoadbuffer*> CompleteTaskArray;
|
||||
|
||||
// load data task buffer
|
||||
class ObLoadbuffer {
|
||||
public:
|
||||
const static int64_t LOAD_BUFFER_MAX_ROW_COUNT = DEFAULT_BUFFERRED_ROW_COUNT;
|
||||
ObLoadbuffer()
|
||||
: tenant_id_(common::OB_INVALID_ID),
|
||||
table_id_(common::OB_INVALID_ID),
|
||||
insert_column_num_(0),
|
||||
stored_row_cnt_(0),
|
||||
stored_pos_(0),
|
||||
task_id_(common::OB_INVALID_ID),
|
||||
part_id_(common::OB_INVALID_PARTITION_ID),
|
||||
task_status_(0),
|
||||
insert_mode_(false),
|
||||
returned_timestamp_(0),
|
||||
field_data_allocator_(common::ObModIds::OB_SQL_EXECUTOR),
|
||||
array_allocator_(common::ObModIds::OB_SQL_EXECUTOR),
|
||||
insert_column_names_(common::OB_MALLOC_NORMAL_BLOCK_SIZE, array_allocator_),
|
||||
expr_bitset_(array_allocator_),
|
||||
insert_values_(common::OB_MALLOC_NORMAL_BLOCK_SIZE, array_allocator_),
|
||||
file_line_number_(common::OB_MALLOC_NORMAL_BLOCK_SIZE, array_allocator_),
|
||||
failed_inserted_row_idx_(common::OB_MALLOC_NORMAL_BLOCK_SIZE, array_allocator_),
|
||||
error_codes_(common::OB_MALLOC_NORMAL_BLOCK_SIZE, array_allocator_)
|
||||
|
||||
{}
|
||||
~ObLoadbuffer()
|
||||
{}
|
||||
int init_array();
|
||||
int deep_copy_str(const common::ObString& src, common::ObString& dest);
|
||||
int store_row(const common::ObIArray<common::ObString>& row_strs, int64_t cur_line_number);
|
||||
OB_INLINE bool is_full()
|
||||
{
|
||||
return LOAD_BUFFER_MAX_ROW_COUNT == stored_row_cnt_;
|
||||
}
|
||||
OB_INLINE bool is_empty()
|
||||
{
|
||||
return 0 == stored_row_cnt_ && 0 == stored_pos_;
|
||||
}
|
||||
OB_INLINE void reuse()
|
||||
{
|
||||
task_status_ = 0;
|
||||
stored_row_cnt_ = 0;
|
||||
stored_pos_ = 0;
|
||||
task_id_ = common::OB_INVALID_ID;
|
||||
returned_timestamp_ = 0;
|
||||
ip_addr_.reset();
|
||||
field_data_allocator_.reuse();
|
||||
failed_inserted_row_idx_.reuse();
|
||||
error_codes_.reuse();
|
||||
}
|
||||
|
||||
OB_INLINE void set_addr(common::ObAddr addr)
|
||||
{
|
||||
ip_addr_ = addr;
|
||||
}
|
||||
OB_INLINE common::ObAddr get_addr()
|
||||
{
|
||||
return ip_addr_;
|
||||
}
|
||||
OB_INLINE void set_returned_timestamp(int64_t timestamp)
|
||||
{
|
||||
returned_timestamp_ = timestamp;
|
||||
}
|
||||
OB_INLINE int64_t get_returned_timestamp()
|
||||
{
|
||||
return returned_timestamp_;
|
||||
}
|
||||
OB_INLINE void set_task_status(int64_t status)
|
||||
{
|
||||
task_status_ = status;
|
||||
}
|
||||
OB_INLINE int64_t& get_task_status()
|
||||
{
|
||||
return task_status_;
|
||||
}
|
||||
OB_INLINE void set_task_id(int64_t task_id)
|
||||
{
|
||||
task_id_ = task_id;
|
||||
}
|
||||
OB_INLINE int64_t get_task_id()
|
||||
{
|
||||
return task_id_;
|
||||
}
|
||||
OB_INLINE void set_part_id(int64_t part_id)
|
||||
{
|
||||
part_id_ = part_id;
|
||||
}
|
||||
OB_INLINE int64_t get_part_id()
|
||||
{
|
||||
return part_id_;
|
||||
}
|
||||
OB_INLINE void set_table_id(uint64_t table_id)
|
||||
{
|
||||
table_id_ = table_id;
|
||||
}
|
||||
OB_INLINE uint64_t get_table_id()
|
||||
{
|
||||
return table_id_;
|
||||
}
|
||||
OB_INLINE void set_tenant_id(uint64_t tenant_id)
|
||||
{
|
||||
tenant_id_ = tenant_id;
|
||||
}
|
||||
OB_INLINE uint64_t get_tenant_id()
|
||||
{
|
||||
return tenant_id_;
|
||||
}
|
||||
OB_INLINE void set_column_num(int64_t insert_column_num)
|
||||
{
|
||||
insert_column_num_ = insert_column_num;
|
||||
}
|
||||
OB_INLINE int64_t get_column_num()
|
||||
{
|
||||
return insert_column_num_;
|
||||
}
|
||||
OB_INLINE int64_t get_stored_pos()
|
||||
{
|
||||
return stored_pos_;
|
||||
}
|
||||
OB_INLINE int64_t get_stored_row_count()
|
||||
{
|
||||
return stored_row_cnt_;
|
||||
}
|
||||
OB_INLINE void set_table_name(common::ObString& table_name)
|
||||
{
|
||||
table_name_ = table_name;
|
||||
}
|
||||
OB_INLINE common::ObString& get_table_name()
|
||||
{
|
||||
return table_name_;
|
||||
}
|
||||
OB_INLINE ObExprValueBitSet& get_expr_bitset()
|
||||
{
|
||||
return expr_bitset_;
|
||||
}
|
||||
OB_INLINE void set_load_mode(ObLoadDupActionType insert_mode)
|
||||
{
|
||||
insert_mode_ = static_cast<int64_t>(insert_mode);
|
||||
}
|
||||
OB_INLINE ObLoadDupActionType get_load_mode()
|
||||
{
|
||||
return static_cast<ObLoadDupActionType>(insert_mode_);
|
||||
}
|
||||
int set_allocator_tenant();
|
||||
int prepare_insert_info(const common::ObIArray<common::ObString>& column_names, ObExprValueBitSet& expr_value_bitset);
|
||||
common::ObIArray<common::ObString>& get_insert_values()
|
||||
{
|
||||
return insert_values_;
|
||||
}
|
||||
common::ObIArray<common::ObString>& get_insert_keys()
|
||||
{
|
||||
return insert_column_names_;
|
||||
}
|
||||
common::ObIArray<int64_t>& get_file_line_number()
|
||||
{
|
||||
return file_line_number_;
|
||||
}
|
||||
common::ObIArray<int16_t>& get_failed_row_idx()
|
||||
{
|
||||
return failed_inserted_row_idx_;
|
||||
}
|
||||
common::ObIArray<int>& get_error_code_array()
|
||||
{
|
||||
return error_codes_;
|
||||
}
|
||||
TO_STRING_KV(K_(tenant_id), K_(table_id), K_(insert_column_num), K_(stored_row_cnt), K_(stored_pos), K_(task_id),
|
||||
K_(part_id), K_(task_status), K_(insert_mode), K_(returned_timestamp));
|
||||
OB_UNIS_VERSION(1);
|
||||
|
||||
private:
|
||||
// send params
|
||||
uint64_t tenant_id_;
|
||||
uint64_t table_id_;
|
||||
common::ObString table_name_;
|
||||
int64_t insert_column_num_;
|
||||
int64_t stored_row_cnt_;
|
||||
int64_t stored_pos_;
|
||||
int64_t task_id_;
|
||||
int64_t part_id_;
|
||||
int64_t task_status_;
|
||||
int64_t insert_mode_;
|
||||
int64_t returned_timestamp_;
|
||||
common::ObAddr ip_addr_;
|
||||
// allocator
|
||||
common::ObArenaAllocator field_data_allocator_;
|
||||
common::ModulePageAllocator array_allocator_;
|
||||
// data arrays
|
||||
common::ObSEArray<common::ObString, EXPECTED_INSERT_COLUMN_NUM> insert_column_names_;
|
||||
ObExprValueBitSet expr_bitset_; // true if the value is expr
|
||||
common::ObSEArray<common::ObString, LOAD_BUFFER_MAX_ROW_COUNT> insert_values_;
|
||||
// only used in host server
|
||||
common::ObSEArray<int64_t, LOAD_BUFFER_MAX_ROW_COUNT> file_line_number_; // belongs to [0, file_total_line_number)
|
||||
common::ObSEArray<int16_t, LOAD_BUFFER_MAX_ROW_COUNT> failed_inserted_row_idx_; // idx belongs to [0,
|
||||
// LOAD_BUFFER_MAX_ROW_COUNT)
|
||||
common::ObSEArray<int, LOAD_BUFFER_MAX_ROW_COUNT> error_codes_;
|
||||
};
|
||||
|
||||
// load data task result
|
||||
class ObLoadResult {
|
||||
public:
|
||||
ObLoadResult()
|
||||
: task_id_(-1), part_id_(common::OB_INVALID_PARTITION_ID), affected_rows_(0), failed_rows_(0), task_flags_(false)
|
||||
{}
|
||||
TO_STRING_KV(K_(task_id), K_(part_id), K_(affected_rows), K_(failed_rows), K_(task_flags));
|
||||
int64_t task_id_;
|
||||
int64_t part_id_;
|
||||
int64_t affected_rows_;
|
||||
int64_t failed_rows_;
|
||||
int64_t task_flags_;
|
||||
common::ObSEArray<int16_t, DEFAULT_BUFFERRED_ROW_COUNT> row_number_;
|
||||
common::ObSEArray<int, DEFAULT_BUFFERRED_ROW_COUNT> row_err_code_;
|
||||
OB_UNIS_VERSION(1);
|
||||
};
|
||||
|
||||
class ObRpcLoadDataTaskExecuteP
|
||||
: public oceanbase::obrpc::ObRpcProcessor<obrpc::ObLoadDataRpcProxy::ObRpc<obrpc::OB_LOAD_DATA_EXECUTE> > {
|
||||
public:
|
||||
explicit ObRpcLoadDataTaskExecuteP(const observer::ObGlobalContext& gctx) : gctx_(gctx), escape_data_buffer_()
|
||||
{}
|
||||
virtual ~ObRpcLoadDataTaskExecuteP()
|
||||
{}
|
||||
|
||||
protected:
|
||||
int process();
|
||||
|
||||
private:
|
||||
const observer::ObGlobalContext& gctx_;
|
||||
common::ObDataBuffer escape_data_buffer_;
|
||||
char str_buf_[common::OB_MAX_DEFAULT_VALUE_LENGTH]; // TODO: change this
|
||||
};
|
||||
|
||||
class ObRpcLoadDataTaskCallBack : public obrpc::ObLoadDataRpcProxy::AsyncCB<obrpc::OB_LOAD_DATA_EXECUTE> {
|
||||
public:
|
||||
ObRpcLoadDataTaskCallBack(
|
||||
ObParallelTaskController& task_controller, CompleteTaskArray& complete_task_list, Request* request)
|
||||
: task_controller_(task_controller), complete_task_list_(complete_task_list), request_buffer_ptr_(request)
|
||||
{}
|
||||
virtual void on_timeout();
|
||||
void set_args(const Request& arg);
|
||||
oceanbase::rpc::frame::ObReqTransport::AsyncCB* clone(const oceanbase::rpc::frame::SPAlloc& alloc) const
|
||||
{
|
||||
void* buf = alloc(sizeof(*this));
|
||||
ObRpcLoadDataTaskCallBack* newcb = NULL;
|
||||
if (NULL != buf) {
|
||||
newcb = new (buf) ObRpcLoadDataTaskCallBack(task_controller_, complete_task_list_, request_buffer_ptr_);
|
||||
}
|
||||
return newcb;
|
||||
}
|
||||
int process();
|
||||
|
||||
private:
|
||||
ObParallelTaskController& task_controller_;
|
||||
CompleteTaskArray& complete_task_list_;
|
||||
Request* request_buffer_ptr_;
|
||||
};
|
||||
|
||||
// load data V2
|
||||
|
||||
class ObRpcLoadDataShuffleTaskExecuteP
|
||||
: public oceanbase::obrpc::ObRpcProcessor<obrpc::ObLoadDataRpcProxy::ObRpc<obrpc::OB_LOAD_DATA_SHUFFLE> > {
|
||||
public:
|
||||
explicit ObRpcLoadDataShuffleTaskExecuteP(const observer::ObGlobalContext& gctx) : gctx_(gctx)
|
||||
{}
|
||||
virtual ~ObRpcLoadDataShuffleTaskExecuteP()
|
||||
{}
|
||||
|
||||
protected:
|
||||
int process();
|
||||
|
||||
private:
|
||||
const observer::ObGlobalContext& gctx_;
|
||||
};
|
||||
|
||||
class ObRpcLoadDataShuffleTaskCallBack : public obrpc::ObLoadDataRpcProxy::AsyncCB<obrpc::OB_LOAD_DATA_SHUFFLE> {
|
||||
public:
|
||||
ObRpcLoadDataShuffleTaskCallBack(ObParallelTaskController& task_controller,
|
||||
ObConcurrentFixedCircularArray<ObShuffleTaskHandle*>& complete_task_list, ObShuffleTaskHandle* handle)
|
||||
: task_controller_(task_controller), complete_task_list_(complete_task_list), handle_(handle)
|
||||
{}
|
||||
virtual void on_timeout();
|
||||
void set_args(const Request& arg);
|
||||
oceanbase::rpc::frame::ObReqTransport::AsyncCB* clone(const oceanbase::rpc::frame::SPAlloc& alloc) const
|
||||
{
|
||||
void* buf = alloc(sizeof(*this));
|
||||
ObRpcLoadDataShuffleTaskCallBack* newcb = NULL;
|
||||
if (NULL != buf) {
|
||||
newcb = new (buf) ObRpcLoadDataShuffleTaskCallBack(task_controller_, complete_task_list_, handle_);
|
||||
}
|
||||
return newcb;
|
||||
}
|
||||
int process();
|
||||
int release_resouce();
|
||||
|
||||
private:
|
||||
ObParallelTaskController& task_controller_;
|
||||
ObConcurrentFixedCircularArray<ObShuffleTaskHandle*>& complete_task_list_;
|
||||
ObShuffleTaskHandle* handle_;
|
||||
};
|
||||
|
||||
class ObRpcLoadDataInsertTaskExecuteP
|
||||
: public oceanbase::obrpc::ObRpcProcessor<obrpc::ObLoadDataRpcProxy::ObRpc<obrpc::OB_LOAD_DATA_INSERT> > {
|
||||
public:
|
||||
explicit ObRpcLoadDataInsertTaskExecuteP(const observer::ObGlobalContext& gctx) : gctx_(gctx)
|
||||
{}
|
||||
virtual ~ObRpcLoadDataInsertTaskExecuteP()
|
||||
{}
|
||||
|
||||
protected:
|
||||
int process();
|
||||
|
||||
private:
|
||||
const observer::ObGlobalContext& gctx_;
|
||||
};
|
||||
|
||||
class ObRpcLoadDataInsertTaskCallBack : public obrpc::ObLoadDataRpcProxy::AsyncCB<obrpc::OB_LOAD_DATA_INSERT> {
|
||||
public:
|
||||
ObRpcLoadDataInsertTaskCallBack(ObParallelTaskController& task_controller,
|
||||
ObConcurrentFixedCircularArray<ObInsertTask*>& complete_task_list, ObInsertTask* insert_task)
|
||||
: task_controller_(task_controller), complete_task_list_(complete_task_list), insert_task_(insert_task)
|
||||
{}
|
||||
virtual void on_timeout();
|
||||
void set_args(const Request& arg);
|
||||
oceanbase::rpc::frame::ObReqTransport::AsyncCB* clone(const oceanbase::rpc::frame::SPAlloc& alloc) const
|
||||
{
|
||||
void* buf = alloc(sizeof(*this));
|
||||
ObRpcLoadDataInsertTaskCallBack* newcb = NULL;
|
||||
if (NULL != buf) {
|
||||
newcb = new (buf) ObRpcLoadDataInsertTaskCallBack(task_controller_, complete_task_list_, insert_task_);
|
||||
}
|
||||
return newcb;
|
||||
}
|
||||
int process();
|
||||
int release_resouce();
|
||||
|
||||
private:
|
||||
ObParallelTaskController& task_controller_;
|
||||
ObConcurrentFixedCircularArray<ObInsertTask*>& complete_task_list_;
|
||||
ObInsertTask* insert_task_;
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
||||
#endif // OCEANBASE_SQL_ENGINE_CMD_LOAD_DATA_RPC_H__
|
||||
410
src/sql/engine/cmd/ob_load_data_utils.cpp
Normal file
410
src/sql/engine/cmd/ob_load_data_utils.cpp
Normal file
@ -0,0 +1,410 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
|
||||
#include "sql/engine/cmd/ob_load_data_utils.h"
|
||||
#include "sql/resolver/cmd/ob_load_data_stmt.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
namespace sql {
|
||||
|
||||
const char* ObLoadDataUtils::NULL_STRING = "NULL";
|
||||
const char ObLoadDataUtils::NULL_VALUE_FLAG = '\xff';
|
||||
|
||||
int ObLoadDataUtils::build_insert_sql_string_head(ObLoadDupActionType insert_mode, const ObString& table_name,
|
||||
const ObIArray<ObString>& insert_keys, ObSqlString& insertsql_keys)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
static const char* replace_stmt = "replace into ";
|
||||
static const char* insert_stmt = "insert into ";
|
||||
static const char* insert_ignore_stmt = "insert ignore into ";
|
||||
|
||||
const char* stmt_head = NULL;
|
||||
switch (insert_mode) {
|
||||
case ObLoadDupActionType::LOAD_REPLACE:
|
||||
stmt_head = replace_stmt;
|
||||
break;
|
||||
case ObLoadDupActionType::LOAD_IGNORE:
|
||||
stmt_head = insert_ignore_stmt;
|
||||
break;
|
||||
case ObLoadDupActionType::LOAD_STOP_ON_DUP:
|
||||
stmt_head = insert_stmt;
|
||||
break;
|
||||
default:
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("not suppport insert mode", K(insert_mode));
|
||||
}
|
||||
|
||||
insertsql_keys.reuse();
|
||||
OZ(insertsql_keys.reserve(OB_MEDIUM_SQL_LENGTH));
|
||||
OZ(insertsql_keys.assign(stmt_head));
|
||||
OZ(insertsql_keys.append(table_name));
|
||||
OZ(insertsql_keys.append("("));
|
||||
for (int64_t i = 0; i < insert_keys.count(); ++i) {
|
||||
if (i != 0) {
|
||||
OZ(insertsql_keys.append(","));
|
||||
}
|
||||
OZ(insertsql_keys.append_fmt(
|
||||
share::is_oracle_mode() ? "\"%.*s\"" : "`%.*s`", insert_keys.at(i).length(), insert_keys.at(i).ptr()));
|
||||
}
|
||||
OZ(insertsql_keys.append(")"));
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
LOG_WARN("append failed", K(ret), K(insertsql_keys.length()));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLoadDataUtils::append_values_in_remote_process(int64_t table_column_count, int64_t append_values_count,
|
||||
const ObExprValueBitSet& expr_bitset, const ObIArray<ObString>& insert_values, ObSqlString& insertsql,
|
||||
ObDataBuffer& data_buffer, int64_t skipped_row_count)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!insertsql.is_valid()) ||
|
||||
OB_UNLIKELY(append_values_count + skipped_row_count * table_column_count > insert_values.count()) ||
|
||||
OB_UNLIKELY(0 == table_column_count)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("insert values are invalid", K(ret), K(insertsql), K(append_values_count), K(insert_values.count()));
|
||||
} else {
|
||||
int64_t row_count = append_values_count / table_column_count;
|
||||
if (OB_FAIL(insertsql.append(" values "))) {
|
||||
LOG_WARN("append failed", K(ret), K(insertsql.length()));
|
||||
}
|
||||
for (int64_t row_idx = 0; OB_SUCC(ret) && row_idx < row_count; ++row_idx) {
|
||||
if (OB_FAIL(append_values_for_one_row(
|
||||
table_column_count, expr_bitset, insert_values, insertsql, data_buffer, row_idx + skipped_row_count))) {
|
||||
LOG_WARN("append values for one row in remote process failed", K(ret));
|
||||
} else {
|
||||
if (row_idx + 1 != row_count) {
|
||||
if (OB_FAIL(insertsql.append(","))) {
|
||||
LOG_WARN("append failed", K(ret), K(insertsql.length()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLoadDataUtils::append_values_for_one_row(const int64_t table_column_count,
|
||||
const ObExprValueBitSet& expr_value_bitset, const ObIArray<ObString>& insert_values, ObSqlString& insertsql,
|
||||
ObDataBuffer& data_buffer, const int64_t skipped_row_count)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t value_offset = skipped_row_count * table_column_count;
|
||||
|
||||
if (OB_UNLIKELY(skipped_row_count * table_column_count + table_column_count > insert_values.count())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(skipped_row_count), K(table_column_count), K(insert_values.count()));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(insertsql.append("("))) {
|
||||
LOG_WARN("append failed", K(ret), K(insertsql.length()));
|
||||
}
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < table_column_count; ++i) {
|
||||
const ObString& value = insert_values.at(i + value_offset);
|
||||
bool is_expr_value = expr_value_bitset.has_member(i);
|
||||
ObString cur_column_str;
|
||||
if (!is_expr_value) {
|
||||
cur_column_str = escape_quotation(value, data_buffer);
|
||||
remove_last_slash(cur_column_str);
|
||||
} else {
|
||||
cur_column_str = value;
|
||||
}
|
||||
if (i != 0) {
|
||||
if (OB_FAIL(insertsql.append(","))) {
|
||||
LOG_WARN("append failed", K(ret), K(insertsql.length()));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(append_value(cur_column_str, insertsql, is_expr_value))) {
|
||||
LOG_WARN("append failed", K(ret), K(insertsql.length()), K(cur_column_str));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(insertsql.append(")"))) {
|
||||
LOG_WARN("append failed", K(ret), K(insertsql.length()));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLoadDataUtils::append_value(const ObString& cur_column_str, ObSqlString& sqlstr_values, bool is_expr_value)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!is_expr_value) {
|
||||
if (is_null_field(cur_column_str)) {
|
||||
if (OB_FAIL(sqlstr_values.append(NULL_STRING))) {
|
||||
LOG_WARN("append failed", K(ret));
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(sqlstr_values.append_fmt("'%.*s'", cur_column_str.length(), cur_column_str.ptr()))) {
|
||||
LOG_WARN("append failed", K(ret));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(sqlstr_values.append(cur_column_str))) {
|
||||
LOG_WARN("append failed", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLoadDataUtils::append_values_in_local_process(const int64_t key_columns, const int64_t values_count,
|
||||
const ObIArray<ObString>& insert_values, const ObExprValueBitSet& expr_value_bitset, ObSqlString& insertsql,
|
||||
ObDataBuffer& data_buffer)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!insertsql.is_valid() || values_count > insert_values.count() || key_columns != values_count) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("insert values are invalid", K(ret), K(insertsql), K(values_count), K(insert_values.count()));
|
||||
} else {
|
||||
if (OB_FAIL(insertsql.append(" values "))) {
|
||||
LOG_WARN("append failed", K(ret), K(insertsql.length()));
|
||||
} else if (OB_FAIL(
|
||||
append_values_for_one_row(values_count, expr_value_bitset, insert_values, insertsql, data_buffer))) {
|
||||
LOG_WARN("append values for one row in local process failed", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObString ObLoadDataUtils::escape_quotation(const ObString& value, ObDataBuffer& data_buf)
|
||||
{
|
||||
char* buf = data_buf.get_data();
|
||||
ObString result;
|
||||
|
||||
if (OB_ISNULL(buf)) {
|
||||
LOG_WARN("data buf is not inited");
|
||||
} else {
|
||||
// check if escape is needed
|
||||
bool need_escape = false;
|
||||
const char* src = value.ptr();
|
||||
int64_t str_len = value.length();
|
||||
ObLoadEscapeSM escape_sm;
|
||||
escape_sm.set_escape_char(ObLoadEscapeSM::ESCAPE_CHAR_MYSQL);
|
||||
for (int64_t i = 0; !need_escape && i < str_len; ++i) {
|
||||
if (*(src + i) == '\'' && !escape_sm.is_escaping()) {
|
||||
need_escape = true;
|
||||
}
|
||||
escape_sm.shift_by_input(*(src + i));
|
||||
}
|
||||
|
||||
if (!need_escape) {
|
||||
result = value;
|
||||
} else {
|
||||
int64_t pos = 0;
|
||||
escape_sm.reset();
|
||||
for (int64_t i = 0; i < str_len && pos < data_buf.get_capacity(); ++i) {
|
||||
if (*(src + i) == '\'' && !escape_sm.is_escaping()) {
|
||||
buf[pos++] = static_cast<char>(
|
||||
share::is_oracle_mode() ? ObLoadEscapeSM::ESCAPE_CHAR_ORACLE : ObLoadEscapeSM::ESCAPE_CHAR_MYSQL);
|
||||
}
|
||||
buf[pos++] = src[i];
|
||||
escape_sm.shift_by_input(*(src + i));
|
||||
}
|
||||
if (OB_UNLIKELY(pos >= data_buf.get_capacity())) {
|
||||
LOG_ERROR("data is too long"); // this should never happened, just for protection
|
||||
result.reset();
|
||||
} else {
|
||||
result.assign_ptr(buf, static_cast<int32_t>(pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int ObLoadDataUtils::init_empty_string_array(ObIArray<ObString>& new_array, int64_t array_size)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
new_array.reset();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < array_size; ++i) {
|
||||
if (OB_FAIL(new_array.push_back(ObString::make_empty_string()))) {
|
||||
LOG_WARN("push back empty string failed", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObKMPStateMachine::scan_buf(char*& cur_pos, const char* buf_end)
|
||||
{
|
||||
bool matched = false;
|
||||
if (OB_UNLIKELY(!is_inited_ || NULL == cur_pos)) {
|
||||
LOG_ERROR("ObKmpStateMachine not inited.", K(cur_pos), K(buf_end));
|
||||
} else {
|
||||
for (; !matched && cur_pos < buf_end; cur_pos++) {
|
||||
while (matched_pos_ > 0 && *cur_pos != str_[matched_pos_]) {
|
||||
matched_pos_ = next_[matched_pos_];
|
||||
}
|
||||
if (*cur_pos == str_[matched_pos_]) {
|
||||
matched_pos_++;
|
||||
}
|
||||
if (matched_pos_ == str_len_) {
|
||||
matched_pos_ = 0;
|
||||
matched = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return matched;
|
||||
}
|
||||
|
||||
int ObKMPStateMachine::init(ObIAllocator& allocator, const ObString& str)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
void* next_buff = NULL;
|
||||
void* str_buff = NULL;
|
||||
int32_t str_len = str.length();
|
||||
if (OB_UNLIKELY(is_inited_)) {
|
||||
ret = OB_INIT_TWICE;
|
||||
LOG_WARN("init failed, init twice.", K(ret));
|
||||
} else if (OB_UNLIKELY(str_len > KEY_WORD_MAX_LENGTH) || OB_UNLIKELY(str_len <= 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("init failed, invalid argument.", K(ret));
|
||||
} else if (OB_ISNULL(next_buff = allocator.alloc(str_len * sizeof(int32_t)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("init failed, no memory.", K(ret), K(str_len));
|
||||
} else if (OB_ISNULL(str_buff = allocator.alloc(str_len * sizeof(char)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("init failed, no memory.", K(ret), K(str_len));
|
||||
} else {
|
||||
str_len_ = str_len;
|
||||
next_ = static_cast<int32_t*>(next_buff);
|
||||
str_ = static_cast<char*>(str_buff);
|
||||
// copy string
|
||||
MEMCPY(str_, str.ptr(), str.length());
|
||||
matched_pos_ = 0;
|
||||
// calc kmp next arr
|
||||
int32_t k = 0;
|
||||
next_[0] = 0;
|
||||
for (int64_t i = 1; i < str_len_; ++i) {
|
||||
while (k > 0 && str_[k] != str_[i]) {
|
||||
k = next_[k];
|
||||
}
|
||||
if (str_[k] == str_[i]) {
|
||||
k++;
|
||||
}
|
||||
next_[i] = k;
|
||||
}
|
||||
// check error
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < str_len_; ++i) {
|
||||
if (OB_UNLIKELY(next_[i] < 0) || OB_UNLIKELY(next_[i] >= str_len_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("check next value failed", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
is_inited_ = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLoadDataUtils::check_session_status(ObSQLSessionInfo& session, int64_t reserved_us)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool is_timeout = false;
|
||||
int64_t query_timeout = 0;
|
||||
int64_t query_start_time = session.get_query_start_time();
|
||||
int64_t current_time = ObTimeUtil::current_time();
|
||||
|
||||
if (OB_FAIL(session.get_query_timeout(query_timeout))) {
|
||||
LOG_WARN("fail to get query timeout", K(ret));
|
||||
} else if (OB_FAIL(session.is_timeout(is_timeout))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get session timeout info failed", K(ret));
|
||||
} else if (OB_UNLIKELY(query_start_time + query_timeout < current_time + reserved_us)) {
|
||||
ret = OB_TIMEOUT;
|
||||
LOG_WARN("query is timeout", K(ret));
|
||||
} else if (OB_UNLIKELY(is_timeout)) {
|
||||
ret = OB_TIMEOUT;
|
||||
LOG_WARN("session is timeout", K(ret));
|
||||
} else if (OB_UNLIKELY(session.is_query_killed())) {
|
||||
ret = OB_ERR_QUERY_INTERRUPTED;
|
||||
LOG_WARN("query is killed", K(ret));
|
||||
} else if (OB_UNLIKELY(session.is_zombie())) {
|
||||
ret = OB_SESSION_KILLED;
|
||||
LOG_WARN("session is killed", K(ret));
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
LOG_WARN(
|
||||
"LOAD DATA timeout", K(ret), K(session.get_sessid()), K(query_timeout), K(query_start_time), K(current_time));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGlobalLoadDataStatMap::init()
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (IS_INIT) {
|
||||
ret = OB_INIT_TWICE;
|
||||
} else if (OB_FAIL(map_.create(bucket_num, ObModIds::OB_SQL_LOAD_DATA, ObModIds::OB_SQL_LOAD_DATA))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("create hash table failed", K(ret));
|
||||
} else {
|
||||
is_inited_ = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGlobalLoadDataStatMap::register_job(const ObLoadDataGID& id, ObLoadDataStat* job_status)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (IS_NOT_INIT) {
|
||||
ret = OB_NOT_INIT;
|
||||
}
|
||||
OZ(map_.set_refactored(id, job_status));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGlobalLoadDataStatMap::unregister_job(const ObLoadDataGID& id, ObLoadDataStat*& job_status)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (IS_NOT_INIT) {
|
||||
ret = OB_NOT_INIT;
|
||||
}
|
||||
OZ(map_.erase_refactored(id, &job_status));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObGlobalLoadDataStatMap::get_job_status(const ObLoadDataGID& id, ObLoadDataStat*& job_status)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
auto get_and_add_ref = [&](hash::HashMapPair<ObLoadDataGID, ObLoadDataStat*>& entry) -> void {
|
||||
entry.second->aquire();
|
||||
job_status = entry.second;
|
||||
};
|
||||
OZ(map_.read_atomic(id, get_and_add_ref));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObGlobalLoadDataStatMap* ObGlobalLoadDataStatMap::getInstance()
|
||||
{
|
||||
return instance_;
|
||||
}
|
||||
|
||||
ObGlobalLoadDataStatMap* ObGlobalLoadDataStatMap::instance_ = new ObGlobalLoadDataStatMap();
|
||||
|
||||
volatile int64_t ObLoadDataGID::GlobalLoadDataID = 0;
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObLoadTaskStatus, task_status_);
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObLoadDataGID, id);
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
360
src/sql/engine/cmd/ob_load_data_utils.h
Normal file
360
src/sql/engine/cmd/ob_load_data_utils.h
Normal file
@ -0,0 +1,360 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "share/ob_define.h"
|
||||
#include "lib/container/ob_se_array.h"
|
||||
#include "lib/container/ob_bit_set.h"
|
||||
#include "lib/string/ob_sql_string.h"
|
||||
#include "lib/hash/ob_hashmap.h"
|
||||
#include "common/object/ob_object.h"
|
||||
|
||||
#ifndef OCEANBASE_SQL_ENGINE_CMD_LOAD_DATA_UTILS_H_
|
||||
#define OCEANBASE_SQL_ENGINE_CMD_LOAD_DATA_UTILS_H_
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
|
||||
enum class ObLoadTaskResultFlag;
|
||||
enum class ObLoadDupActionType;
|
||||
class ObSQLSessionInfo;
|
||||
|
||||
typedef common::ObBitSet<common::OB_DEFAULT_BITSET_SIZE_FOR_BASE_COLUMN> ObExprValueBitSet;
|
||||
|
||||
/* A state machine to handle backslash from a char stream */
|
||||
class ObLoadEscapeSM {
|
||||
public:
|
||||
static const int64_t ESCAPE_CHAR_MYSQL = static_cast<int64_t>('\\');
|
||||
static const int64_t ESCAPE_CHAR_ORACLE = static_cast<int64_t>('\'');
|
||||
ObLoadEscapeSM() : is_escaped_flag_(false), escape_char_(INT64_MAX), escaped_char_count(0)
|
||||
{}
|
||||
OB_INLINE void shift_by_input(char c)
|
||||
{
|
||||
/* there are 4 situations:
|
||||
* 1. STATE : c == \\ && is_escaped_flag_ == True Action: is_escaped_flag_ = False
|
||||
* 2. STATE : c == \\ && is_escaped_flag_ == False Action: is_escaped_flag_ = True
|
||||
* 3. STATE : c != \\ && is_escaped_flag_ == True Action: is_escaped_flag_ = False
|
||||
* 4. STATE : c != \\ && is_escaped_flag_ == False Action: is_escaped_flag_ = False
|
||||
* only state 1-3 need to change is_escaped_flag_, but usual case is state 4
|
||||
*/
|
||||
if (OB_LIKELY(static_cast<int64_t>(c) != escape_char_ && !is_escaped_flag_)) {
|
||||
// situation 4, do nothing
|
||||
} else {
|
||||
// situation 1-3
|
||||
is_escaped_flag_ = !is_escaped_flag_;
|
||||
if (is_escaped_flag_) {
|
||||
escaped_char_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
OB_INLINE bool is_escaping()
|
||||
{
|
||||
return is_escaped_flag_;
|
||||
}
|
||||
void set_escape_char(int64_t escape_char)
|
||||
{
|
||||
escape_char_ = escape_char;
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
is_escaped_flag_ = false;
|
||||
escaped_char_count = 0;
|
||||
}
|
||||
int64_t get_escaped_char_count()
|
||||
{
|
||||
return escaped_char_count;
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_escaped_flag_;
|
||||
int64_t escape_char_;
|
||||
int64_t escaped_char_count;
|
||||
};
|
||||
|
||||
class ObLoadDataUtils {
|
||||
public:
|
||||
static const char* NULL_STRING;
|
||||
static const char NULL_VALUE_FLAG;
|
||||
|
||||
static inline void remove_last_slash(common::ObString& value)
|
||||
{
|
||||
const char* data = value.ptr();
|
||||
int32_t data_len = value.length();
|
||||
if (OB_LIKELY(data_len) > 0 && OB_UNLIKELY(data[data_len - 1] == '\\')) {
|
||||
bool is_escaped = false;
|
||||
for (int32_t i = data_len - 2; i >= 0 && data[i] == '\\'; --i) {
|
||||
is_escaped = !is_escaped;
|
||||
}
|
||||
if (!is_escaped) {
|
||||
value.assign_ptr(data, data_len - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int str_write_buf(const common::ObString& str, char*& buf, int64_t& buf_len)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
int64_t data_len = str.length();
|
||||
if (OB_UNLIKELY(buf_len <= data_len)) {
|
||||
ret = common::OB_SIZE_OVERFLOW;
|
||||
} else {
|
||||
MEMCPY(buf, str.ptr(), data_len);
|
||||
buf += data_len;
|
||||
buf_len -= data_len;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int char_write_buf(char c, char*& buf, int64_t& buf_len)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (OB_UNLIKELY(buf_len <= 1)) {
|
||||
ret = common::OB_SIZE_OVERFLOW;
|
||||
} else {
|
||||
buf[0] = c;
|
||||
buf++;
|
||||
buf_len--;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int escape_str_write_buf(const common::ObHexEscapeSqlStr& str, char*& buf, int64_t& buf_len)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
int64_t data_len = str.to_string(buf, buf_len);
|
||||
if (OB_UNLIKELY(buf_len <= data_len)) {
|
||||
ret = common::OB_SIZE_OVERFLOW;
|
||||
} else {
|
||||
buf += data_len;
|
||||
buf_len -= data_len;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool is_null_field(const common::ObString& field_str)
|
||||
{
|
||||
int ret_bool = false;
|
||||
if (field_str.length() == 1 && *field_str.ptr() == NULL_VALUE_FLAG) {
|
||||
ret_bool = true;
|
||||
}
|
||||
return ret_bool;
|
||||
}
|
||||
|
||||
static common::ObString escape_quotation(const common::ObString& value, common::ObDataBuffer& data_buf);
|
||||
static int init_empty_string_array(common::ObIArray<common::ObString>& new_array, int64_t array_size);
|
||||
|
||||
static int build_insert_sql_string_head(ObLoadDupActionType insert_mode, const common::ObString& table_name,
|
||||
const common::ObIArray<common::ObString>& insert_keys, common::ObSqlString& insertsql_keys);
|
||||
static int append_values_in_remote_process(int64_t table_column_count, int64_t append_values_count,
|
||||
const ObExprValueBitSet& expr_bitset, const common::ObIArray<common::ObString>& insert_values,
|
||||
common::ObSqlString& insertsql, common::ObDataBuffer& data_buffer, int64_t skipped_row_count = 0);
|
||||
static int append_values_for_one_row(const int64_t table_column_count, const ObExprValueBitSet& expr_value_bitset,
|
||||
const common::ObIArray<common::ObString>& insert_values, common::ObSqlString& insertsql,
|
||||
common::ObDataBuffer& data_buffer, const int64_t skipped_row_count = 0);
|
||||
static int append_value(
|
||||
const common::ObString& cur_column_str, common::ObSqlString& sqlstr_values, bool is_expr_value);
|
||||
static int append_values_in_local_process(const int64_t key_columns, const int64_t values_count,
|
||||
const common::ObIArray<common::ObString>& insert_values, const ObExprValueBitSet& expr_value_bitset,
|
||||
common::ObSqlString& insertsql, common::ObDataBuffer& data_buffer);
|
||||
|
||||
static inline bool has_flag(int64_t& task_status, int64_t flag)
|
||||
{
|
||||
return 0 != (task_status & (1 << flag));
|
||||
}
|
||||
static inline void set_flag(int64_t& task_status, int64_t flag)
|
||||
{
|
||||
task_status |= (1 << flag);
|
||||
}
|
||||
|
||||
static int check_session_status(ObSQLSessionInfo& session, int64_t reserved_us = 0);
|
||||
};
|
||||
|
||||
class ObLoadTaskStatus {
|
||||
public:
|
||||
ObLoadTaskStatus() : task_status_(0)
|
||||
{}
|
||||
enum class ResFlag {
|
||||
HAS_FAILED_ROW = 0,
|
||||
ALL_ROWS_FAILED,
|
||||
NEED_WAIT_MINOR_FREEZE,
|
||||
TIMEOUT,
|
||||
RPC_CALLBACK_PROCESS_ERROR,
|
||||
RPC_REMOTE_PROCESS_ERROR,
|
||||
INVALID_MAX_FLAG
|
||||
};
|
||||
static_assert(static_cast<int64_t>(ResFlag::INVALID_MAX_FLAG) < 64,
|
||||
"ObLoadTaskResultFlag max value should less than bit size of int64_t");
|
||||
OB_INLINE void set_flag(ResFlag flag)
|
||||
{
|
||||
task_status_ |= (1 << static_cast<int64_t>(flag));
|
||||
}
|
||||
OB_INLINE bool has_flag(ResFlag flag)
|
||||
{
|
||||
return 0 != (task_status_ & (1 << static_cast<int64_t>(flag)));
|
||||
}
|
||||
TO_STRING_KV(K_(task_status));
|
||||
OB_UNIS_VERSION(1);
|
||||
|
||||
private:
|
||||
int64_t task_status_;
|
||||
};
|
||||
|
||||
class ObLoadDataTimer {
|
||||
public:
|
||||
ObLoadDataTimer() : total_time_us_(0), temp_start_time_us_(-1)
|
||||
{}
|
||||
OB_INLINE void start_stat()
|
||||
{
|
||||
#ifdef TIME_STAT_ON
|
||||
temp_start_time_us_ = ObTimeUtility::current_time();
|
||||
#endif
|
||||
}
|
||||
OB_INLINE void end_stat()
|
||||
{
|
||||
#ifdef TIME_STAT_ON
|
||||
if (temp_start_time_us_ != -1) {
|
||||
total_time_us_ += (ObTimeUtility::current_time() - temp_start_time_us_);
|
||||
temp_start_time_us_ = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
int64_t get_wait_secs() const
|
||||
{
|
||||
return total_time_us_ / 1000000;
|
||||
}
|
||||
TO_STRING_KV("secs", get_wait_secs());
|
||||
|
||||
private:
|
||||
int64_t total_time_us_;
|
||||
int64_t temp_start_time_us_;
|
||||
};
|
||||
|
||||
/*
|
||||
* ObKMPStateMachine is a str matcher
|
||||
* efficently implimented using KMP algorithem
|
||||
* to detect a given str from a char stream
|
||||
*/
|
||||
class ObKMPStateMachine {
|
||||
public:
|
||||
ObKMPStateMachine() : is_inited_(false), str_(NULL), str_len_(0), matched_pos_(0), next_(NULL)
|
||||
{}
|
||||
int init(common::ObIAllocator& allocator, const common::ObString& str);
|
||||
/*
|
||||
* accept one char at a time, and update the state of the detector
|
||||
* return true if succ matching target str ending with the current char
|
||||
*/
|
||||
OB_INLINE bool accept_char(const char c)
|
||||
{
|
||||
bool ret_bool = false;
|
||||
if (OB_UNLIKELY(!is_inited_)) {
|
||||
SQL_ENG_LOG(ERROR, "ObKmpSeparatorDetector not inited.");
|
||||
} else {
|
||||
while (matched_pos_ > 0 && c != str_[matched_pos_]) {
|
||||
matched_pos_ = next_[matched_pos_];
|
||||
}
|
||||
if (c == str_[matched_pos_]) {
|
||||
matched_pos_++;
|
||||
}
|
||||
if (matched_pos_ == str_len_) {
|
||||
matched_pos_ = 0;
|
||||
ret_bool = true;
|
||||
}
|
||||
}
|
||||
return ret_bool;
|
||||
}
|
||||
OB_INLINE int32_t get_pattern_length()
|
||||
{
|
||||
return str_len_;
|
||||
}
|
||||
bool scan_buf(char*& cur_pos, const char* buf_end);
|
||||
void reuse()
|
||||
{
|
||||
matched_pos_ = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
static const int KEY_WORD_MAX_LENGTH = 2 * 1024;
|
||||
bool is_inited_;
|
||||
char* str_; // string pattern for matching
|
||||
int32_t str_len_;
|
||||
int32_t matched_pos_; // can opt to pointer
|
||||
int32_t* next_; // next array of KMP algorithm
|
||||
};
|
||||
|
||||
struct ObLoadDataGID {
|
||||
static volatile int64_t GlobalLoadDataID;
|
||||
static void generate_new_id(ObLoadDataGID& gid)
|
||||
{
|
||||
gid.id = ATOMIC_AAF(&GlobalLoadDataID, 1);
|
||||
}
|
||||
ObLoadDataGID() : id(-1)
|
||||
{}
|
||||
bool is_valid() const
|
||||
{
|
||||
return id > 0;
|
||||
}
|
||||
uint64_t hash() const
|
||||
{
|
||||
return common::murmurhash(&id, sizeof(id), 0);
|
||||
}
|
||||
bool operator==(const ObLoadDataGID& other) const
|
||||
{
|
||||
return id == other.id;
|
||||
}
|
||||
void operator=(const ObLoadDataGID& other)
|
||||
{
|
||||
id = other.id;
|
||||
}
|
||||
int64_t id;
|
||||
TO_STRING_KV(K(id));
|
||||
OB_UNIS_VERSION(1);
|
||||
};
|
||||
|
||||
struct ObLoadDataStat {
|
||||
ObLoadDataStat() : ref_cnt_(0)
|
||||
{}
|
||||
int64_t aquire()
|
||||
{
|
||||
return ATOMIC_AAF(&ref_cnt_, 1);
|
||||
}
|
||||
int64_t release()
|
||||
{
|
||||
return ATOMIC_AAF(&ref_cnt_, -1);
|
||||
}
|
||||
int64_t get_ref_cnt()
|
||||
{
|
||||
return ATOMIC_LOAD(&ref_cnt_);
|
||||
}
|
||||
|
||||
volatile int64_t ref_cnt_;
|
||||
};
|
||||
|
||||
class ObGlobalLoadDataStatMap {
|
||||
public:
|
||||
static ObGlobalLoadDataStatMap* getInstance();
|
||||
ObGlobalLoadDataStatMap() : is_inited_(false)
|
||||
{}
|
||||
int init();
|
||||
int register_job(const ObLoadDataGID& id, ObLoadDataStat* job_status);
|
||||
int unregister_job(const ObLoadDataGID& id, ObLoadDataStat*& job_status);
|
||||
int get_job_status(const ObLoadDataGID& id, ObLoadDataStat*& job_status);
|
||||
|
||||
private:
|
||||
typedef common::hash::ObHashMap<ObLoadDataGID, ObLoadDataStat*, common::hash::SpinReadWriteDefendMode> HASH_MAP;
|
||||
static const int64_t bucket_num = 1000;
|
||||
static ObGlobalLoadDataStatMap* instance_;
|
||||
HASH_MAP map_;
|
||||
bool is_inited_;
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
||||
#endif // OCEANBASE_SQL_ENGINE_CMD_LOAD_DATA_UTILS_H_
|
||||
438
src/sql/engine/cmd/ob_outline_executor.cpp
Normal file
438
src/sql/engine/cmd/ob_outline_executor.cpp
Normal file
@ -0,0 +1,438 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/engine/cmd/ob_outline_executor.h"
|
||||
|
||||
#include "lib/string/ob_string.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
#include "share/schema/ob_schema_getter_guard.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
#include "share/stat/ob_stat_manager.h"
|
||||
#include "observer/ob_server_struct.h"
|
||||
#include "sql/ob_sql.h"
|
||||
#include "sql/resolver/ddl/ob_create_outline_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_alter_outline_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_drop_outline_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/parser/ob_parser.h"
|
||||
#include "sql/optimizer/ob_log_plan.h"
|
||||
#include "sql/engine/ob_physical_plan_ctx.h"
|
||||
#include "sql/rewrite/ob_transformer_impl.h"
|
||||
#include "sql/rewrite/ob_transform_simplify.h"
|
||||
#include "sql/resolver/ob_schema_checker.h"
|
||||
#include "sql/optimizer/ob_optimizer.h"
|
||||
#include "sql/optimizer/ob_optimizer_context.h"
|
||||
#include "sql/optimizer/ob_optimizer_partition_location_cache.h"
|
||||
#include "sql/optimizer/ob_log_plan_factory.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/plan_cache/ob_cache_object_factory.h"
|
||||
#include "sql/ob_sql_partition_location_cache.h"
|
||||
|
||||
namespace oceanbase {
|
||||
|
||||
using namespace common;
|
||||
using namespace share::schema;
|
||||
using namespace obrpc;
|
||||
|
||||
namespace sql {
|
||||
|
||||
int ObOutlineExecutor::generate_outline_info2(
|
||||
ObExecContext& ctx, ObCreateOutlineStmt* create_outline_stmt, ObOutlineInfo& outline_info)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
outline_info.set_tenant_id(ctx.get_my_session()->get_effective_tenant_id());
|
||||
outline_info.set_outline_content(create_outline_stmt->get_hint());
|
||||
outline_info.set_sql_id(create_outline_stmt->get_sql_id());
|
||||
|
||||
if (create_outline_stmt->get_max_concurrent() >= 0) {
|
||||
ObMaxConcurrentParam concurrent_param(&ctx.get_allocator());
|
||||
concurrent_param.concurrent_num_ = create_outline_stmt->get_max_concurrent();
|
||||
if (OB_FAIL(outline_info.add_param(concurrent_param))) {
|
||||
LOG_WARN("fail to add param", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOutlineExecutor::generate_outline_info(
|
||||
ObExecContext& ctx, ObCreateOutlineStmt* outline_stmt, ObOutlineInfo& outline_info)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObCreateOutlineStmt* create_outline_stmt = reinterpret_cast<ObCreateOutlineStmt*>(outline_stmt);
|
||||
if (create_outline_stmt->get_outline_stmt() == NULL) {
|
||||
ret = generate_outline_info2(ctx, create_outline_stmt, outline_info);
|
||||
} else {
|
||||
ObDMLStmt* outline_stmt = static_cast<ObDMLStmt*>(create_outline_stmt->get_outline_stmt());
|
||||
ret = generate_outline_info1(ctx, outline_stmt, outline_info);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOutlineExecutor::generate_outline_info1(ObExecContext& ctx, ObDMLStmt* outline_stmt, ObOutlineInfo& outline_info)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool has_questionmark_in_outline_sql = false;
|
||||
ObString outline;
|
||||
ObString outline_key;
|
||||
ObString& outline_sql = outline_info.get_sql_text_str();
|
||||
int64_t max_concurrent = -1;
|
||||
;
|
||||
ObMaxConcurrentParam concurrent_param(&ctx.get_allocator());
|
||||
if (OB_ISNULL(ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid ctx", K(ret));
|
||||
} else if (OB_ISNULL(outline_stmt)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid outline stmt is NULL", K(ret));
|
||||
} else if (OB_FAIL(ObSQLUtils::get_outline_key(ctx.get_allocator(),
|
||||
ctx.get_my_session(),
|
||||
outline_sql,
|
||||
outline_key,
|
||||
concurrent_param.fixed_param_store_,
|
||||
FP_PARAMERIZE_AND_FILTER_HINT_MODE,
|
||||
has_questionmark_in_outline_sql))) {
|
||||
LOG_WARN("fail to get outline key", "outline_sql", outline_sql, K(ret));
|
||||
} else if (FALSE_IT(max_concurrent = outline_stmt->get_stmt_hint().max_concurrent_)) {
|
||||
} else if (OB_UNLIKELY(has_questionmark_in_outline_sql && max_concurrent < 0)) {
|
||||
ret = OB_INVALID_OUTLINE;
|
||||
LOG_USER_ERROR(OB_INVALID_OUTLINE, "sql text should have no ? when there is no concurrent limit");
|
||||
LOG_WARN("outline should have no ? when there is no concurrent limit", K(outline_sql), K(ret));
|
||||
} else if (OB_UNLIKELY(max_concurrent >= 0 && outline_stmt->get_stmt_hint().has_hint_exclude_concurrent_)) {
|
||||
ret = OB_INVALID_OUTLINE;
|
||||
LOG_USER_ERROR(OB_INVALID_OUTLINE, "outline and sql concurrent limit can not be mixed");
|
||||
LOG_WARN("outline and sql concurrent limit can not be mixed",
|
||||
"outline_sql_text",
|
||||
outline_info.get_sql_text_str(),
|
||||
K(ret));
|
||||
} else if (OB_FAIL(get_outline(ctx, outline_stmt, outline))) {
|
||||
LOG_WARN("fail to get outline", K(ret));
|
||||
} else {
|
||||
// to check whether ok
|
||||
outline_info.set_outline_content(outline);
|
||||
outline_info.set_tenant_id(ctx.get_my_session()->get_effective_tenant_id());
|
||||
outline_info.set_signature(outline_key);
|
||||
ObString& target_sql = outline_info.get_outline_target_str();
|
||||
if (!target_sql.empty()) {
|
||||
ObString target_key;
|
||||
ObString target_key_with_hint;
|
||||
ObMaxConcurrentParam target_param(&ctx.get_allocator());
|
||||
ObMaxConcurrentParam target_param_with_hint(&ctx.get_allocator());
|
||||
bool has_questionmark_in_target_sql = false;
|
||||
bool is_same_param = true;
|
||||
// get signature derived from to_clause, then check if equal with signature derived from
|
||||
// on_clause
|
||||
if (OB_FAIL(ObSQLUtils::get_outline_key(ctx.get_allocator(),
|
||||
ctx.get_my_session(),
|
||||
target_sql,
|
||||
target_key,
|
||||
target_param.fixed_param_store_,
|
||||
FP_PARAMERIZE_AND_FILTER_HINT_MODE,
|
||||
has_questionmark_in_target_sql))) {
|
||||
LOG_WARN("fail to get outline key", K(target_sql), K(ret));
|
||||
|
||||
} else if (target_key != outline_key || has_questionmark_in_target_sql != has_questionmark_in_outline_sql) {
|
||||
ret = OB_INVALID_OUTLINE;
|
||||
LOG_USER_ERROR(
|
||||
OB_INVALID_OUTLINE, "signature derived from on_clause is not same as signature derived from to_clause");
|
||||
LOG_WARN("outline key is not same with target key",
|
||||
K(outline_sql),
|
||||
K(target_sql),
|
||||
K(has_questionmark_in_target_sql),
|
||||
K(has_questionmark_in_outline_sql),
|
||||
K(ret));
|
||||
} else if (max_concurrent >= 0 &&
|
||||
(OB_FAIL(concurrent_param.same_param_as(target_param, is_same_param)) || !is_same_param)) {
|
||||
if (OB_FAIL(ret)) {
|
||||
LOG_WARN("fail to check if param is same", K(outline_sql), K(target_sql), K(ret));
|
||||
} else {
|
||||
ret = OB_INVALID_OUTLINE;
|
||||
LOG_USER_ERROR(OB_INVALID_OUTLINE,
|
||||
"fixed_param derived from on_clause is not same as fixed_param derived from to_clause");
|
||||
LOG_WARN("outline fixed_param is not same with target fixed_param", K(outline_sql), K(target_sql), K(ret));
|
||||
}
|
||||
} else if (OB_FAIL(ObSQLUtils::get_outline_key(ctx.get_allocator(),
|
||||
ctx.get_my_session(),
|
||||
target_sql,
|
||||
target_key_with_hint,
|
||||
target_param_with_hint.fixed_param_store_,
|
||||
FP_MODE,
|
||||
has_questionmark_in_target_sql))) {
|
||||
LOG_WARN("fail to get outline key", K(target_sql), K(ret));
|
||||
} else {
|
||||
// replace outline_key with target_key derived from to_clause with index not filtered
|
||||
outline_info.set_signature(target_key_with_hint);
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
// set concurrent limit info to ObOutlineInfo
|
||||
if (max_concurrent < 0) {
|
||||
// if concurrent num is negative, you should reset the max concurrent param store
|
||||
} else {
|
||||
concurrent_param.concurrent_num_ = max_concurrent;
|
||||
if (OB_FAIL(outline_info.add_param(concurrent_param))) {
|
||||
LOG_WARN("fail to add param", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOutlineExecutor::generate_logical_plan(
|
||||
ObExecContext& ctx, ObOptimizerContext& opt_ctx, ObDMLStmt* outline_stmt, ObLogPlan*& logical_plan)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session_info = ctx.get_my_session();
|
||||
ObPhysicalPlan* phy_plan = NULL;
|
||||
ObOptimizer optimizer(opt_ctx);
|
||||
if (OB_ISNULL(session_info) || OB_ISNULL(outline_stmt) || OB_ISNULL(opt_ctx.get_location_cache())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid parameter", K(session_info), K(outline_stmt));
|
||||
} else if (OB_FAIL(
|
||||
ObCacheObjectFactory::alloc(phy_plan, OUTLINE_EXEC_HANDLE, session_info->get_effective_tenant_id()))) {
|
||||
LOG_WARN("fail to alloc phy_plan", K(ret));
|
||||
} else if (OB_ISNULL(phy_plan)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_ERROR("Failed to alloc physical plan from tc factory", K(ret));
|
||||
} else if (OB_FAIL(ObSql::calc_pre_calculable_exprs(
|
||||
outline_stmt->get_calculable_exprs(), ctx, *outline_stmt, *phy_plan))) {
|
||||
LOG_WARN("fail to calc pre calculable expr", K(ret));
|
||||
} else if (OB_FAIL(ObSql::transform_stmt(opt_ctx.get_sql_schema_guard(),
|
||||
static_cast<ObOptimizerPartitionLocationCache*>(opt_ctx.get_location_cache())->get_location_cache(),
|
||||
opt_ctx.get_partition_service(),
|
||||
opt_ctx.get_stat_manager(),
|
||||
opt_ctx.get_opt_stat_manager(),
|
||||
&opt_ctx.get_local_server_addr(),
|
||||
opt_ctx.get_merged_version(),
|
||||
phy_plan,
|
||||
ctx,
|
||||
outline_stmt))) {
|
||||
LOG_WARN("fail to transform outline stmt", K(ret));
|
||||
} else if (OB_FAIL(ObSql::optimize_stmt(optimizer, *session_info, *outline_stmt, logical_plan))) {
|
||||
LOG_WARN("fail to optimize stmt", K(ret));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
|
||||
if (OB_LIKELY(phy_plan != NULL)) {
|
||||
ObCacheObjectFactory::free(phy_plan, OUTLINE_EXEC_HANDLE);
|
||||
phy_plan = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObOutlineExecutor::is_valid_outline_stmt_type(stmt::StmtType type)
|
||||
{
|
||||
return type == stmt::T_SELECT || type == stmt::T_INSERT || type == stmt::T_UPDATE || type == stmt::T_REPLACE ||
|
||||
type == stmt::T_DELETE;
|
||||
}
|
||||
|
||||
int ObOutlineExecutor::print_outline(ObExecContext& ctx, ObLogPlan* log_plan, ObString& outline)
|
||||
{
|
||||
void* tmp_ptr = NULL;
|
||||
char* buf = NULL;
|
||||
int64_t pos = 0;
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(log_plan)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to get log plan", K(ret), K(log_plan));
|
||||
} else if (OB_UNLIKELY(NULL == (tmp_ptr = ctx.get_allocator().alloc(
|
||||
OB_MAX_SQL_LENGTH)))) { // the same as __all_outline column outline_content
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_ERROR("fail to alloc memory", K(ret));
|
||||
} else if (FALSE_IT(buf = static_cast<char*>(tmp_ptr))) {
|
||||
} else if (OB_FAIL(log_plan->print_outline_oneline(buf, OB_MAX_SQL_LENGTH, pos))) {
|
||||
LOG_WARN("fail to print outline", K(ret), K(buf), K(pos));
|
||||
} else {
|
||||
outline.assign_ptr(buf, static_cast<ObString::obstr_size_t>(pos));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOutlineExecutor::get_outline(ObExecContext& ctx, ObDMLStmt* outline_stmt, ObString& outline)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session_info = ctx.get_my_session();
|
||||
ObPhysicalPlanCtx* pctx = ctx.get_physical_plan_ctx();
|
||||
ObLogPlan* log_plan = NULL;
|
||||
|
||||
if (OB_ISNULL(session_info) || OB_ISNULL(pctx) || OB_ISNULL(outline_stmt) || OB_ISNULL(GCTX.merged_version_) ||
|
||||
OB_ISNULL(ctx.get_sql_ctx()) || OB_ISNULL(ctx.get_sql_ctx()->sql_schema_guard_.get_schema_guard())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid parameter", K(session_info), K(pctx), K(outline_stmt), K(GCTX.merged_version_));
|
||||
} else if (!is_valid_outline_stmt_type(outline_stmt->get_stmt_type())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected outline stmt type", K(outline_stmt->get_stmt_type()), K(ret));
|
||||
} else {
|
||||
if (outline_stmt->get_stmt_hint().is_only_concurrent_hint()) {
|
||||
// do not generate outline_content
|
||||
} else if (OB_ISNULL(ctx.get_expr_factory())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(ret), K(ctx.get_expr_factory()));
|
||||
} else {
|
||||
ObSqlPartitionLocationCache sql_partition_location_cache;
|
||||
sql_partition_location_cache.init(
|
||||
GCTX.location_cache_, GCTX.self_addr_, ctx.get_virtual_table_ctx().schema_guard_);
|
||||
ObQueryHint query_hint = outline_stmt->get_stmt_hint().get_query_hint();
|
||||
ObOptimizerPartitionLocationCache optimizer_location_cache(ctx.get_allocator(), &sql_partition_location_cache);
|
||||
ObOptimizerContext optctx(session_info,
|
||||
&ctx,
|
||||
&ctx.get_sql_ctx()->sql_schema_guard_,
|
||||
&ObStatManager::get_instance(),
|
||||
&ObOptStatManager::get_instance(),
|
||||
GCTX.par_ser_,
|
||||
ctx.get_allocator(),
|
||||
&optimizer_location_cache,
|
||||
&pctx->get_param_store(),
|
||||
GCTX.self_addr_,
|
||||
GCTX.srv_rpc_proxy_,
|
||||
*GCTX.merged_version_,
|
||||
query_hint,
|
||||
*ctx.get_expr_factory(),
|
||||
outline_stmt);
|
||||
if (OB_FAIL(generate_logical_plan(ctx, optctx, outline_stmt, log_plan))) {
|
||||
LOG_WARN("fail to generate logical plan", K(ret));
|
||||
} else if (OB_FAIL(print_outline(ctx, log_plan, outline))) {
|
||||
LOG_WARN("fail to print outline", K(ret));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateOutlineExecutor::execute(ObExecContext& ctx, ObCreateOutlineStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObString outline_key;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
ObCreateOutlineArg& arg = stmt.get_create_outline_arg();
|
||||
ObOutlineInfo& outline_info = arg.outline_info_;
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
arg.ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(generate_outline_info(ctx, &stmt, outline_info))) {
|
||||
LOG_WARN("generate_outline_info failed", K(ret));
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed", K(ret));
|
||||
} else if (OB_FAIL(ctx.get_sql_ctx()->schema_guard_->reset())) {
|
||||
LOG_WARN("schema_guard reset failed", K(ret));
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->create_outline(arg))) {
|
||||
LOG_WARN("rpc proxy create outline failed", "dst", common_rpc_proxy->get_server(), K(ret));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObAlterOutlineExecutor::execute(ObExecContext& ctx, ObAlterOutlineStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObString outline_key;
|
||||
ObString outline;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
ObAlterOutlineArg& arg = stmt.get_alter_outline_arg();
|
||||
ObOutlineInfo& outline_info = arg.alter_outline_info_;
|
||||
ObDMLStmt* outline_stmt = static_cast<ObDMLStmt*>(stmt.get_outline_stmt());
|
||||
ObString& outline_sql = stmt.get_outline_sql();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
arg.ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(outline_stmt)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("outline stmt is empty", K(ret));
|
||||
} else if (OB_FAIL(generate_outline_info1(ctx, outline_stmt, outline_info))) {
|
||||
LOG_WARN("generate_outline_info failed", K(outline_sql), K(ret));
|
||||
} else {
|
||||
ObAlterOutlineInfo& alter_outline_info = arg.alter_outline_info_;
|
||||
int64_t index = OB_INVALID_INDEX;
|
||||
bool has_limit_param = false;
|
||||
if (OB_FAIL(alter_outline_info.has_concurrent_limit_param(has_limit_param))) {
|
||||
LOG_WARN("fail to judge whether outline_info has concurrent_limit_param", K(ret));
|
||||
} else if (has_limit_param) {
|
||||
index = ObAlterOutlineArg::ADD_CONCURRENT_LIMIT;
|
||||
} else if (!alter_outline_info.get_outline_content_str().empty()) {
|
||||
index = ObAlterOutlineArg::ADD_OUTLINE_CONTENT;
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid alter outline info", K(alter_outline_info), K(ret));
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && OB_FAIL(alter_outline_info.get_alter_option_bitset().add_member(index))) {
|
||||
LOG_WARN("failed to add member to alter_option_bitset", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_FAIL(ctx.get_sql_ctx()->schema_guard_->reset())) {
|
||||
LOG_WARN("schema_guard reset failed", K(ret));
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->alter_outline(arg))) {
|
||||
LOG_WARN("rpc proxy alter outline failed", "dst", common_rpc_proxy->get_server(), K(ret));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDropOutlineExecutor::execute(ObExecContext& ctx, ObDropOutlineStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObDropOutlineArg arg = stmt.get_drop_outline_arg();
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
arg.ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->drop_outline(arg))) {
|
||||
LOG_WARN("rpc proxy drop outline failed", K(ret), "dst", common_rpc_proxy->get_server());
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
98
src/sql/engine/cmd/ob_outline_executor.h
Normal file
98
src/sql/engine/cmd/ob_outline_executor.h
Normal file
@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_OB_CREATE_OUTLINE_EXECUTOR_H_
|
||||
#define OCEANBASE_SQL_OB_CREATE_OUTLINE_EXECUTOR_H_
|
||||
|
||||
#include "lib/container/ob_vector.h"
|
||||
#include "sql/parser/parse_node.h"
|
||||
#include "sql/resolver/ob_stmt_type.h"
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
class ObString;
|
||||
}
|
||||
namespace share {
|
||||
namespace schema {
|
||||
class ObOutlineInfo;
|
||||
}
|
||||
} // namespace share
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObCreateOutlineStmt;
|
||||
class ObAlterOutlineStmt;
|
||||
class ObDropOutlineStmt;
|
||||
class ObLogPlan;
|
||||
class ObDMLStmt;
|
||||
class ObOptimizerContext;
|
||||
|
||||
class ObOutlineExecutor {
|
||||
public:
|
||||
ObOutlineExecutor()
|
||||
{}
|
||||
virtual ~ObOutlineExecutor()
|
||||
{}
|
||||
|
||||
protected:
|
||||
int get_outline(ObExecContext& ctx, ObDMLStmt* outline_stmt, common::ObString& outline);
|
||||
int generate_outline_info(
|
||||
ObExecContext& ctx, ObCreateOutlineStmt* outline_stmt, share::schema::ObOutlineInfo& outline_info);
|
||||
int generate_outline_info1(ObExecContext& ctx, ObDMLStmt* outline_stmt, share::schema::ObOutlineInfo& outline_info);
|
||||
int generate_outline_info2(
|
||||
ObExecContext& ctx, ObCreateOutlineStmt* outline_stmt, share::schema::ObOutlineInfo& outline_info);
|
||||
int generate_logical_plan(
|
||||
ObExecContext& ctx, ObOptimizerContext& opt_ctx, ObDMLStmt* outline_stmt, ObLogPlan*& logical_plan);
|
||||
bool is_valid_outline_stmt_type(stmt::StmtType type);
|
||||
int print_outline(ObExecContext& ctx, ObLogPlan* log_plan, common::ObString& outline);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObOutlineExecutor);
|
||||
};
|
||||
|
||||
class ObCreateOutlineExecutor : public ObOutlineExecutor {
|
||||
public:
|
||||
ObCreateOutlineExecutor()
|
||||
{}
|
||||
virtual ~ObCreateOutlineExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObCreateOutlineStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObCreateOutlineExecutor);
|
||||
};
|
||||
|
||||
class ObAlterOutlineExecutor : public ObOutlineExecutor {
|
||||
public:
|
||||
ObAlterOutlineExecutor()
|
||||
{}
|
||||
virtual ~ObAlterOutlineExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObAlterOutlineStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObAlterOutlineExecutor);
|
||||
};
|
||||
|
||||
class ObDropOutlineExecutor {
|
||||
public:
|
||||
ObDropOutlineExecutor()
|
||||
{}
|
||||
virtual ~ObDropOutlineExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObDropOutlineStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObDropOutlineExecutor);
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif // OCEANBASE_SQL_OB_CREATE_OUTLINE_EXECUTOR_H_
|
||||
1197
src/sql/engine/cmd/ob_partition_executor_utils.cpp
Normal file
1197
src/sql/engine/cmd/ob_partition_executor_utils.cpp
Normal file
File diff suppressed because it is too large
Load Diff
113
src/sql/engine/cmd/ob_partition_executor_utils.h
Normal file
113
src/sql/engine/cmd/ob_partition_executor_utils.h
Normal file
@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_OB_PARTITION_EXECUTOR_UTILS_
|
||||
#define OCEANBASE_SQL_OB_PARTITION_EXECUTOR_UTILS_
|
||||
#include "common/object/ob_object.h"
|
||||
#include "lib/container/ob_se_array.h"
|
||||
#include "common/sql_mode/ob_sql_mode.h"
|
||||
#include "sql/resolver/ob_stmt_type.h"
|
||||
#include "sql/engine/expr/ob_expr_res_type.h"
|
||||
#include "sql/resolver/ddl/ob_table_stmt.h"
|
||||
namespace oceanbase {
|
||||
namespace share {
|
||||
namespace schema {
|
||||
class ObPartition;
|
||||
class ObSubPartition;
|
||||
} // namespace schema
|
||||
} // namespace share
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObRawExpr;
|
||||
class ObCreateTableStmt;
|
||||
class ObCreateTablegroupStmt;
|
||||
class ObCreateIndexStmt;
|
||||
class ObTableStmt;
|
||||
class ObTablegroupStmt;
|
||||
|
||||
class ObPartitionExecutorUtils {
|
||||
public:
|
||||
const static int OB_DEFAULT_ARRAY_SIZE = 16;
|
||||
static int calc_values_exprs(ObExecContext& ctx, ObCreateTableStmt& stmt);
|
||||
static int calc_values_exprs(ObExecContext& ctx, ObCreateIndexStmt& stmt);
|
||||
static int calc_values_exprs_for_alter_table(
|
||||
ObExecContext& ctx, share::schema::ObTableSchema& table_schema, ObPartitionedStmt& stmt);
|
||||
|
||||
static int cast_list_expr_to_obj(ObExecContext& ctx, const stmt::StmtType stmt_type, const bool is_subpart,
|
||||
const int64_t real_part_num, share::schema::ObPartition** partition_array,
|
||||
share::schema::ObSubPartition** subpartition_array, common::ObIArray<ObRawExpr*>& list_fun_expr,
|
||||
common::ObIArray<ObRawExpr*>& list_values_exprs);
|
||||
|
||||
static int cast_expr_to_obj(ObExecContext& ctx, const stmt::StmtType stmt_type, bool is_list_part,
|
||||
common::ObIArray<ObRawExpr*>& partition_fun_expr, common::ObIArray<ObRawExpr*>& partition_value_exprs,
|
||||
common::ObIArray<common::ObObj>& partition_value_objs);
|
||||
|
||||
static int set_range_part_high_bound(ObExecContext& ctx, const stmt::StmtType stmt_type,
|
||||
share::schema::ObTableSchema& table_schema, ObPartitionedStmt& stmt, bool is_subpart);
|
||||
|
||||
/*--------------tablegroup related start------------------*/
|
||||
static int calc_values_exprs(ObExecContext& ctx, ObCreateTablegroupStmt& stmt);
|
||||
|
||||
static int calc_values_exprs(ObExecContext& ctx, ObCreateTablegroupStmt& stmt, bool is_subpart);
|
||||
|
||||
static int cast_range_expr_to_obj(ObExecContext& ctx, ObCreateTablegroupStmt& stmt, bool is_subpart,
|
||||
common::ObIArray<common::ObObj>& range_partition_obj);
|
||||
|
||||
static int cast_range_expr_to_obj(ObExecContext& ctx, common::ObIArray<ObRawExpr*>& range_values_exprs,
|
||||
const int64_t fun_expr_num, const stmt::StmtType stmt_type, const bool is_subpart, const int64_t real_part_num,
|
||||
share::schema::ObPartition** partition_array, share::schema::ObSubPartition** subpartition_array,
|
||||
common::ObIArray<common::ObObj>& range_partition_obj);
|
||||
|
||||
static int cast_list_expr_to_obj(ObExecContext& ctx, ObCreateTablegroupStmt& stmt, bool is_subpar);
|
||||
|
||||
static int cast_list_expr_to_obj(ObExecContext& ctx, ObTablegroupStmt& stmt, const bool is_subpart,
|
||||
share::schema::ObPartition** partition_array, share::schema::ObSubPartition** subpartition_array);
|
||||
|
||||
static int cast_expr_to_obj(ObExecContext& ctx, int64_t fun_expr_num,
|
||||
common::ObIArray<ObRawExpr*>& range_values_exprs, common::ObIArray<common::ObObj>& range_partition_obj);
|
||||
/*--------------tablegroup related end------------------*/
|
||||
|
||||
static int calc_range_values_exprs(ObExecContext& ctx, ObCreateIndexStmt& stmt);
|
||||
|
||||
template <typename T>
|
||||
static int check_increasing_range_value(T** array, int64_t part_num, const stmt::StmtType stmt_type);
|
||||
|
||||
static int expr_cal_and_cast(const sql::stmt::StmtType& stmt_type, bool is_list_part, ObExecContext& ctx,
|
||||
const common::ObObjType fun_expr_type, const common::ObCollationType fun_collation_type, ObRawExpr* expr,
|
||||
common::ObObj& value_obj);
|
||||
|
||||
static int expr_cal_and_cast_with_check_varchar_len(const stmt::StmtType& stmt_type, bool is_list_part,
|
||||
ObExecContext& ctx, const sql::ObExprResType& dst_res_type, ObRawExpr* expr, common::ObObj& value_obj);
|
||||
|
||||
static int set_list_part_rows(ObExecContext& ctx, const stmt::StmtType stmt_type,
|
||||
share::schema::ObTableSchema& table_schema, ObIArray<ObRawExpr*>& list_fun_exprs,
|
||||
ObIArray<ObRawExpr*>& list_values_exprs, bool is_subpart);
|
||||
|
||||
static int set_individual_range_part_high_bound(ObExecContext& ctx, const stmt::StmtType stmt_type,
|
||||
share::schema::ObTableSchema& table_schema, ObPartitionedStmt& stmt);
|
||||
|
||||
static int set_individual_list_part_rows(ObExecContext& ctx, const stmt::StmtType stmt_type,
|
||||
share::schema::ObTableSchema& table_schema, ObIArray<ObRawExpr*>& list_fun_exprs,
|
||||
ObDDLStmt::array_array_t& list_values_exprs_array);
|
||||
|
||||
static int row_expr_to_array(ObRawExpr* row_expr, ObIArray<ObRawExpr*>& list_values_expr_array);
|
||||
|
||||
private:
|
||||
static int calc_values_exprs(ObExecContext& ctx, const stmt::StmtType stmt_type,
|
||||
share::schema::ObTableSchema& table_schema, ObPartitionedStmt& stmt, bool is_subpart);
|
||||
|
||||
static int sort_list_paritition_if_need(share::schema::ObTableSchema& table_schema);
|
||||
};
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
|
||||
#endif // OCEANBASE_SQL_OB_PARTITION_EXECUTOR_UTILS_
|
||||
49
src/sql/engine/cmd/ob_profile_cmd_executor.cpp
Normal file
49
src/sql/engine/cmd/ob_profile_cmd_executor.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/engine/cmd/ob_profile_cmd_executor.h"
|
||||
|
||||
#include "lib/encrypt/ob_encrypted_helper.h"
|
||||
#include "lib/string/ob_sql_string.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "sql/resolver/ddl/ob_create_profile_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace obrpc;
|
||||
using namespace share::schema;
|
||||
namespace sql {
|
||||
|
||||
int ObProfileDDLExecutor::execute(ObExecContext& ctx, ObUserProfileStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
|
||||
if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed");
|
||||
} else if (OB_FAIL(common_rpc_proxy->do_profile_ddl(stmt.get_ddl_arg()))) {
|
||||
LOG_WARN("Create profile error", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
43
src/sql/engine/cmd/ob_profile_cmd_executor.h
Normal file
43
src/sql/engine/cmd/ob_profile_cmd_executor.h
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_ENGINE_CMD_PROFILE_CMD_EXECUTOR_
|
||||
#define OCEANBASE_SQL_ENGINE_CMD_PROFILE_CMD_EXECUTOR_
|
||||
#include "lib/string/ob_string.h"
|
||||
#include "lib/container/ob_array_serialization.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace obrpc {
|
||||
class ObCommonRpcProxy;
|
||||
class ObUserProfileArg;
|
||||
class ObDropUserArg;
|
||||
} // namespace obrpc
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObUserProfileStmt;
|
||||
class ObProfileDDLExecutor {
|
||||
public:
|
||||
ObProfileDDLExecutor()
|
||||
{}
|
||||
virtual ~ObProfileDDLExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObUserProfileStmt& stmt);
|
||||
|
||||
private:
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObProfileDDLExecutor);
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif // OCEANBASE_SQL_ENGINE_CMD_PROFILE_CMD_EXECUTOR_
|
||||
223
src/sql/engine/cmd/ob_resource_executor.cpp
Normal file
223
src/sql/engine/cmd/ob_resource_executor.cpp
Normal file
@ -0,0 +1,223 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/engine/cmd/ob_resource_executor.h"
|
||||
#include "sql/resolver/cmd/ob_resource_stmt.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
|
||||
using namespace oceanbase::common;
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
|
||||
ObCreateResourcePoolExecutor::ObCreateResourcePoolExecutor()
|
||||
{}
|
||||
|
||||
ObCreateResourcePoolExecutor::~ObCreateResourcePoolExecutor()
|
||||
{}
|
||||
|
||||
int ObCreateResourcePoolExecutor::execute(ObExecContext& ctx, ObCreateResourcePoolStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObCreateResourcePoolArg& create_resource_pool_arg = stmt.get_arg();
|
||||
|
||||
if (NULL == (task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (NULL == (common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed");
|
||||
} else if (OB_SUCCESS != (ret = common_rpc_proxy->create_resource_pool(create_resource_pool_arg))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy create resource_pool failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObAlterResourcePoolExecutor::ObAlterResourcePoolExecutor()
|
||||
{}
|
||||
|
||||
ObAlterResourcePoolExecutor::~ObAlterResourcePoolExecutor()
|
||||
{}
|
||||
|
||||
int ObAlterResourcePoolExecutor::execute(ObExecContext& ctx, ObAlterResourcePoolStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObAlterResourcePoolArg& alter_resource_pool_arg = stmt.get_arg();
|
||||
|
||||
if (NULL == (task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (NULL == (common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed");
|
||||
} else if (OB_SUCCESS != (ret = common_rpc_proxy->alter_resource_pool(alter_resource_pool_arg))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy alter resource_pool failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObSplitResourcePoolExecutor::ObSplitResourcePoolExecutor()
|
||||
{}
|
||||
|
||||
ObSplitResourcePoolExecutor::~ObSplitResourcePoolExecutor()
|
||||
{}
|
||||
|
||||
int ObSplitResourcePoolExecutor::execute(ObExecContext& ctx, ObSplitResourcePoolStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObSplitResourcePoolArg& split_resource_pool_arg = stmt.get_arg();
|
||||
|
||||
if (NULL == (task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed", K(ret));
|
||||
} else if (NULL == (common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed", K(ret));
|
||||
} else if (OB_SUCCESS != (ret = common_rpc_proxy->split_resource_pool(split_resource_pool_arg))) {
|
||||
SQL_ENG_LOG(WARN, "send split resource pool failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObMergeResourcePoolExecutor::ObMergeResourcePoolExecutor()
|
||||
{}
|
||||
|
||||
ObMergeResourcePoolExecutor::~ObMergeResourcePoolExecutor()
|
||||
{}
|
||||
|
||||
int ObMergeResourcePoolExecutor::execute(ObExecContext& ctx, ObMergeResourcePoolStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObMergeResourcePoolArg& merge_resource_pool_arg = stmt.get_arg();
|
||||
|
||||
if (NULL == (task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (NULL == (common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed");
|
||||
} else if (OB_SUCCESS != (ret = common_rpc_proxy->merge_resource_pool(merge_resource_pool_arg))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy merge resource_pool failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObDropResourcePoolExecutor::ObDropResourcePoolExecutor()
|
||||
{}
|
||||
|
||||
ObDropResourcePoolExecutor::~ObDropResourcePoolExecutor()
|
||||
{}
|
||||
|
||||
int ObDropResourcePoolExecutor::execute(ObExecContext& ctx, ObDropResourcePoolStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObDropResourcePoolArg& drop_resource_pool_arg = stmt.get_arg();
|
||||
|
||||
if (NULL == (task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (NULL == (common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed");
|
||||
} else if (OB_SUCCESS != (ret = common_rpc_proxy->drop_resource_pool(drop_resource_pool_arg))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy drop resource_pool failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObCreateResourceUnitExecutor::ObCreateResourceUnitExecutor()
|
||||
{}
|
||||
|
||||
ObCreateResourceUnitExecutor::~ObCreateResourceUnitExecutor()
|
||||
{}
|
||||
|
||||
int ObCreateResourceUnitExecutor::execute(ObExecContext& ctx, ObCreateResourceUnitStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObCreateResourceUnitArg& create_resource_unit_arg = stmt.get_arg();
|
||||
|
||||
if (NULL == (task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (NULL == (common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed");
|
||||
} else if (OB_SUCCESS != (ret = common_rpc_proxy->create_resource_unit(create_resource_unit_arg))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy create resource_unit failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObAlterResourceUnitExecutor::ObAlterResourceUnitExecutor()
|
||||
{}
|
||||
|
||||
ObAlterResourceUnitExecutor::~ObAlterResourceUnitExecutor()
|
||||
{}
|
||||
|
||||
int ObAlterResourceUnitExecutor::execute(ObExecContext& ctx, ObAlterResourceUnitStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObAlterResourceUnitArg& alter_resource_unit_arg = stmt.get_arg();
|
||||
|
||||
if (NULL == (task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (NULL == (common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed");
|
||||
} else if (OB_SUCCESS != (ret = common_rpc_proxy->alter_resource_unit(alter_resource_unit_arg))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy alter resource_unit failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObDropResourceUnitExecutor::ObDropResourceUnitExecutor()
|
||||
{}
|
||||
|
||||
ObDropResourceUnitExecutor::~ObDropResourceUnitExecutor()
|
||||
{}
|
||||
|
||||
int ObDropResourceUnitExecutor::execute(ObExecContext& ctx, ObDropResourceUnitStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObDropResourceUnitArg& drop_resource_unit_arg = stmt.get_arg();
|
||||
|
||||
if (NULL == (task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (NULL == (common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed");
|
||||
} else if (OB_SUCCESS != (ret = common_rpc_proxy->drop_resource_unit(drop_resource_unit_arg))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy drop resource_unit failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
102
src/sql/engine/cmd/ob_resource_executor.h
Normal file
102
src/sql/engine/cmd/ob_resource_executor.h
Normal file
@ -0,0 +1,102 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef __OB_SQL_RESOURCE_EXECUTOR_H__
|
||||
#define __OB_SQL_RESOURCE_EXECUTOR_H__
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObCreateResourcePoolStmt;
|
||||
class ObDropResourcePoolStmt;
|
||||
class ObSplitResourcePoolStmt;
|
||||
class ObMergeResourcePoolStmt;
|
||||
class ObAlterResourcePoolStmt;
|
||||
class ObCreateResourceUnitStmt;
|
||||
class ObAlterResourceUnitStmt;
|
||||
class ObDropResourceUnitStmt;
|
||||
|
||||
class ObCreateResourcePoolExecutor {
|
||||
public:
|
||||
ObCreateResourcePoolExecutor();
|
||||
virtual ~ObCreateResourcePoolExecutor();
|
||||
int execute(ObExecContext& ctx, ObCreateResourcePoolStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObDropResourcePoolExecutor {
|
||||
public:
|
||||
ObDropResourcePoolExecutor();
|
||||
virtual ~ObDropResourcePoolExecutor();
|
||||
int execute(ObExecContext& ctx, ObDropResourcePoolStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObSplitResourcePoolExecutor {
|
||||
public:
|
||||
ObSplitResourcePoolExecutor();
|
||||
virtual ~ObSplitResourcePoolExecutor();
|
||||
int execute(ObExecContext& ctx, ObSplitResourcePoolStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObMergeResourcePoolExecutor {
|
||||
public:
|
||||
ObMergeResourcePoolExecutor();
|
||||
virtual ~ObMergeResourcePoolExecutor();
|
||||
int execute(ObExecContext& ctx, ObMergeResourcePoolStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObAlterResourcePoolExecutor {
|
||||
public:
|
||||
ObAlterResourcePoolExecutor();
|
||||
virtual ~ObAlterResourcePoolExecutor();
|
||||
int execute(ObExecContext& ctx, ObAlterResourcePoolStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObCreateResourceUnitExecutor {
|
||||
public:
|
||||
ObCreateResourceUnitExecutor();
|
||||
virtual ~ObCreateResourceUnitExecutor();
|
||||
int execute(ObExecContext& ctx, ObCreateResourceUnitStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObAlterResourceUnitExecutor {
|
||||
public:
|
||||
ObAlterResourceUnitExecutor();
|
||||
virtual ~ObAlterResourceUnitExecutor();
|
||||
int execute(ObExecContext& ctx, ObAlterResourceUnitStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObDropResourceUnitExecutor {
|
||||
public:
|
||||
ObDropResourceUnitExecutor();
|
||||
virtual ~ObDropResourceUnitExecutor();
|
||||
int execute(ObExecContext& ctx, ObDropResourceUnitStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif /* __OB_SQL_RESOURCE_EXECUTOR_H__ */
|
||||
//// end of header file
|
||||
91
src/sql/engine/cmd/ob_restore_executor.cpp
Normal file
91
src/sql/engine/cmd/ob_restore_executor.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "sql/resolver/cmd/ob_alter_system_stmt.h"
|
||||
#include "sql/engine/cmd/ob_restore_executor.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace share::schema;
|
||||
namespace sql {
|
||||
|
||||
ObRestoreTenantExecutor::ObRestoreTenantExecutor()
|
||||
{}
|
||||
|
||||
ObRestoreTenantExecutor::~ObRestoreTenantExecutor()
|
||||
{}
|
||||
|
||||
int ObRestoreTenantExecutor::execute(ObExecContext& ctx, ObRestoreTenantStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObRestoreTenantArg& restore_tenant_arg = stmt.get_rpc_arg();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObRestoreTenantArg&>(restore_tenant_arg).sql_text_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed", K(ret));
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->restore_tenant(restore_tenant_arg))) {
|
||||
LOG_WARN("rpc proxy restore tenant failed", K(ret), "dst", common_rpc_proxy->get_server());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObPhysicalRestoreTenantExecutor::ObPhysicalRestoreTenantExecutor()
|
||||
{}
|
||||
|
||||
ObPhysicalRestoreTenantExecutor::~ObPhysicalRestoreTenantExecutor()
|
||||
{}
|
||||
|
||||
int ObPhysicalRestoreTenantExecutor::execute(ObExecContext& ctx, ObPhysicalRestoreTenantStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObPhysicalRestoreTenantArg& restore_tenant_arg = stmt.get_rpc_arg();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObPhysicalRestoreTenantArg&>(restore_tenant_arg).sql_text_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed", K(ret));
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->physical_restore_tenant(restore_tenant_arg))) {
|
||||
LOG_WARN("rpc proxy restore tenant failed", K(ret), "dst", common_rpc_proxy->get_server());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
38
src/sql/engine/cmd/ob_restore_executor.h
Normal file
38
src/sql/engine/cmd/ob_restore_executor.h
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_OB_RESTORE_EXECUTOR_
|
||||
#define OCEANBASE_SQL_OB_RESTORE_EXECUTOR_
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObRestoreTenantStmt;
|
||||
class ObPhysicalRestoreTenantStmt;
|
||||
|
||||
class ObRestoreTenantExecutor {
|
||||
public:
|
||||
ObRestoreTenantExecutor();
|
||||
virtual ~ObRestoreTenantExecutor();
|
||||
int execute(ObExecContext& ctx, ObRestoreTenantStmt& stmt);
|
||||
};
|
||||
|
||||
class ObPhysicalRestoreTenantExecutor {
|
||||
public:
|
||||
ObPhysicalRestoreTenantExecutor();
|
||||
virtual ~ObPhysicalRestoreTenantExecutor();
|
||||
int execute(ObExecContext& ctx, ObPhysicalRestoreTenantStmt& stmt);
|
||||
};
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
|
||||
#endif // OCEANBASE_SQL_OB_RESTORE_EXECUTOR_
|
||||
125
src/sql/engine/cmd/ob_role_cmd_executor.cpp
Normal file
125
src/sql/engine/cmd/ob_role_cmd_executor.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/engine/cmd/ob_role_cmd_executor.h"
|
||||
|
||||
#include "lib/encrypt/ob_encrypted_helper.h"
|
||||
#include "lib/string/ob_sql_string.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "sql/resolver/dcl/ob_create_role_stmt.h"
|
||||
#include "sql/resolver/dcl/ob_drop_role_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/engine/cmd/ob_user_cmd_executor.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace obrpc;
|
||||
using namespace share::schema;
|
||||
namespace sql {
|
||||
|
||||
int ObCreateRoleExecutor::execute(ObExecContext& ctx, ObCreateRoleStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const uint64_t tenant_id = stmt.get_tenant_id();
|
||||
const ObString& role_name = stmt.get_role_name();
|
||||
const ObString& pwd = stmt.get_password();
|
||||
if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed");
|
||||
} else {
|
||||
ObCreateUserArg arg;
|
||||
arg.tenant_id_ = tenant_id;
|
||||
arg.exec_tenant_id_ = tenant_id;
|
||||
ObSQLSessionInfo* mysession = ctx.get_my_session();
|
||||
if (OB_ISNULL(mysession)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("failed to get myssion", K(ret));
|
||||
} else {
|
||||
arg.creator_id_ = mysession->get_user_id();
|
||||
}
|
||||
ObUserInfo user_info;
|
||||
user_info.set_tenant_id(tenant_id);
|
||||
user_info.set_type(OB_ROLE);
|
||||
user_info.set_host(OB_DEFAULT_HOST_NAME);
|
||||
ObSArray<int64_t> failed_index;
|
||||
ObString pwd_enc;
|
||||
if (pwd.length() > 0) {
|
||||
char enc_buf[ENC_BUF_LEN] = {0};
|
||||
// user general encrypt of ob
|
||||
if (OB_FAIL(ObCreateUserExecutor::encrypt_passwd(pwd, pwd_enc, enc_buf, ENC_BUF_LEN))) {
|
||||
LOG_WARN("Encrypt password failed", K(ret));
|
||||
} else if (OB_FAIL(user_info.set_passwd(pwd_enc))) {
|
||||
LOG_WARN("set password failed", K(ret));
|
||||
}
|
||||
} else if (OB_FAIL(user_info.set_passwd(pwd_enc))) {
|
||||
LOG_WARN("Failed to set password", K(ret));
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(user_info.set_user_name(role_name))) {
|
||||
LOG_WARN("set user name failed", K(ret));
|
||||
} else if (OB_FAIL(arg.user_infos_.push_back(user_info))) {
|
||||
LOG_WARN("Add user info to array error", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->create_user(arg, failed_index))) {
|
||||
LOG_WARN("Create user error", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDropRoleExecutor::execute(ObExecContext& ctx, ObDropRoleStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const uint64_t tenant_id = stmt.get_tenant_id();
|
||||
if (OB_INVALID_ID == tenant_id) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("tenant is invalid", K(ret));
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed", K(ret));
|
||||
} else if (NULL == (common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else {
|
||||
ObDropUserArg& arg = static_cast<ObDropUserArg&>(stmt.get_ddl_arg());
|
||||
arg.tenant_id_ = tenant_id;
|
||||
arg.exec_tenant_id_ = tenant_id;
|
||||
arg.is_role_ = true;
|
||||
const ObString& role_name = stmt.get_role_name();
|
||||
ObString host_name(OB_DEFAULT_HOST_NAME);
|
||||
ObSArray<int64_t> failed_index;
|
||||
if (OB_FAIL(arg.users_.push_back(role_name))) {
|
||||
LOG_WARN("Add user name failed", K(ret));
|
||||
} else if (OB_FAIL(arg.hosts_.push_back(host_name))) {
|
||||
LOG_WARN("Add host name failed", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->drop_user(arg, failed_index)) || (0 != failed_index.count())) {
|
||||
LOG_WARN("drop role failed", K(ret), K(role_name));
|
||||
// ret = OB_CANNOT_USER;
|
||||
// LOG_USER_ERROR(ret, strlen("DROP ROLE"), "DROP ROLE", role_name.length(), role_name.ptr());
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
66
src/sql/engine/cmd/ob_role_cmd_executor.h
Normal file
66
src/sql/engine/cmd/ob_role_cmd_executor.h
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_ENGINE_CMD_ROLE_CMD_EXECUTOR_
|
||||
#define OCEANBASE_SQL_ENGINE_CMD_ROLE_CMD_EXECUTOR_
|
||||
#include "lib/string/ob_string.h"
|
||||
#include "lib/container/ob_array_serialization.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace obrpc {
|
||||
class ObCommonRpcProxy;
|
||||
class ObCreateRoleArg;
|
||||
class ObDropUserArg;
|
||||
} // namespace obrpc
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObCreateRoleStmt;
|
||||
class ObDropRoleStmt;
|
||||
class ObCreateRoleExecutor {
|
||||
public:
|
||||
ObCreateRoleExecutor()
|
||||
{}
|
||||
virtual ~ObCreateRoleExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObCreateRoleStmt& stmt);
|
||||
static int encrypt_passwd(
|
||||
const common::ObString& passwd, common::ObString& encrypted_passwd, char* enc_buf, int64_t buf_len);
|
||||
|
||||
private:
|
||||
int create_role(obrpc::ObCommonRpcProxy* rpc_proxy, const obrpc::ObCreateRoleArg& arg) const;
|
||||
int drop_role(obrpc::ObCommonRpcProxy* rpc_proxy, const obrpc::ObDropUserArg& arg) const;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObCreateRoleExecutor);
|
||||
};
|
||||
|
||||
class ObDropRoleExecutor {
|
||||
public:
|
||||
ObDropRoleExecutor()
|
||||
{}
|
||||
virtual ~ObDropRoleExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObDropRoleStmt& stmt);
|
||||
static int encrypt_passwd(
|
||||
const common::ObString& passwd, common::ObString& encrypted_passwd, char* enc_buf, int64_t buf_len);
|
||||
|
||||
private:
|
||||
int drop_role(obrpc::ObCommonRpcProxy* rpc_proxy, const obrpc::ObDropUserArg& arg) const;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObDropRoleExecutor);
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif // OCEANBASE_SQL_ENGINE_CMD_USER_CMD_EXECUTOR_
|
||||
57
src/sql/engine/cmd/ob_sequence_executor.cpp
Normal file
57
src/sql/engine/cmd/ob_sequence_executor.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/engine/cmd/ob_sequence_executor.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/resolver/ddl/ob_sequence_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace share;
|
||||
namespace sql {
|
||||
|
||||
#define DEF_SIMPLE_EXECUTOR_IMPL(name, func) \
|
||||
int name##Executor::execute(ObExecContext& ctx, name##Stmt& stmt) \
|
||||
{ \
|
||||
int ret = OB_SUCCESS; \
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL; \
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL; \
|
||||
const obrpc::ObSequenceDDLArg& sequence_arg = stmt.get_arg(); \
|
||||
ObString first_stmt; \
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) { \
|
||||
LOG_WARN("fail to get first stmt", K(ret)); \
|
||||
} else { \
|
||||
const_cast<obrpc::ObSequenceDDLArg&>(sequence_arg).ddl_stmt_str_ = first_stmt; \
|
||||
} \
|
||||
if (OB_FAIL(ret)) { \
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) { \
|
||||
ret = OB_NOT_INIT; \
|
||||
LOG_WARN("get task executor context failed"); \
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) { \
|
||||
ret = OB_NOT_INIT; \
|
||||
LOG_WARN("get common rpc proxy failed"); \
|
||||
} else if (OB_FAIL(common_rpc_proxy->func(sequence_arg))) { \
|
||||
LOG_WARN("rpc proxy failed", K(sequence_arg), K(ret)); \
|
||||
} \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
DEF_SIMPLE_EXECUTOR_IMPL(ObCreateSequence, do_sequence_ddl);
|
||||
DEF_SIMPLE_EXECUTOR_IMPL(ObAlterSequence, do_sequence_ddl);
|
||||
DEF_SIMPLE_EXECUTOR_IMPL(ObDropSequence, do_sequence_ddl);
|
||||
|
||||
#undef DEF_EXECUTOR_IMPL
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
44
src/sql/engine/cmd/ob_sequence_executor.h
Normal file
44
src/sql/engine/cmd/ob_sequence_executor.h
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef __OB_SQL_SEQUENCE_EXECUTOR_H__
|
||||
#define __OB_SQL_SEQUENCE_EXECUTOR_H__
|
||||
#include "share/ob_define.h"
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
#define DEF_SIMPLE_EXECUTOR(name) \
|
||||
class name##Executor { \
|
||||
public: \
|
||||
name##Executor() \
|
||||
{} \
|
||||
virtual ~name##Executor() \
|
||||
{} \
|
||||
int execute(ObExecContext& ctx, name##Stmt& stmt); \
|
||||
\
|
||||
private: \
|
||||
DISALLOW_COPY_AND_ASSIGN(name##Executor); \
|
||||
}
|
||||
|
||||
class ObExecContext;
|
||||
class ObCreateSequenceStmt;
|
||||
class ObDropSequenceStmt;
|
||||
class ObAlterSequenceStmt;
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObCreateSequence);
|
||||
DEF_SIMPLE_EXECUTOR(ObDropSequence);
|
||||
DEF_SIMPLE_EXECUTOR(ObAlterSequence);
|
||||
|
||||
#undef DEF_SIMPLE_EXECUTOR
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif /* __OB_SQL_SEQUENCE_EXECUTOR_H__ */
|
||||
//// end of header file
|
||||
180
src/sql/engine/cmd/ob_set_names_executor.cpp
Normal file
180
src/sql/engine/cmd/ob_set_names_executor.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#include "sql/engine/cmd/ob_set_names_executor.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "lib/string/ob_sql_string.h"
|
||||
#include "share/inner_table/ob_inner_table_schema.h"
|
||||
#include "observer/ob_server_struct.h"
|
||||
using namespace oceanbase::sql;
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::share;
|
||||
using namespace oceanbase::share::schema;
|
||||
|
||||
int ObSetNamesExecutor::execute(ObExecContext& ctx, ObSetNamesStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
if (NULL == (session = ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "session is NULL", K(ret), K(ctx));
|
||||
} else {
|
||||
ObString charset;
|
||||
if (stmt.is_default_charset()) {
|
||||
// Compatible with mysql, take the global character_set_client value
|
||||
if (OB_FAIL(get_global_sys_var_character_set_client(ctx, charset))) {
|
||||
SQL_ENG_LOG(WARN, "fail to get global character_set_client", K(ret));
|
||||
}
|
||||
} else {
|
||||
charset = stmt.get_charset();
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
ObString collation = stmt.get_collation();
|
||||
ObCollationType collation_type = CS_TYPE_INVALID;
|
||||
ObCharsetType cs_type = ObCharset::charset_type(charset);
|
||||
if (CHARSET_INVALID == cs_type) {
|
||||
ret = OB_ERR_UNKNOWN_CHARSET;
|
||||
LOG_USER_ERROR(OB_ERR_UNKNOWN_CHARSET, charset.length(), charset.ptr());
|
||||
} else {
|
||||
charset = ObString::make_string(ObCharset::charset_name(cs_type));
|
||||
if (stmt.is_default_collation() || !collation.empty()) {
|
||||
collation_type = ObCharset::collation_type(collation);
|
||||
if (CS_TYPE_INVALID == collation_type) {
|
||||
ret = OB_ERR_UNKNOWN_COLLATION;
|
||||
LOG_USER_ERROR(OB_ERR_UNKNOWN_COLLATION, collation.length(), collation.ptr());
|
||||
} else if (!ObCharset::is_valid_collation(cs_type, collation_type)) {
|
||||
ret = OB_ERR_COLLATION_MISMATCH;
|
||||
LOG_USER_ERROR(
|
||||
OB_ERR_COLLATION_MISMATCH, collation.length(), collation.ptr(), charset.length(), charset.ptr());
|
||||
} else {
|
||||
collation = ObString::make_string(ObCharset::collation_name(collation_type));
|
||||
}
|
||||
} else {
|
||||
// the use default collation of this charset
|
||||
collation_type = ObCharset::get_default_collation(cs_type);
|
||||
collation = ObString::make_string(ObCharset::collation_name(collation_type));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (!ObCharset::is_valid_connection_collation(collation_type)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
SQL_ENG_LOG(WARN,
|
||||
"collation type not supported",
|
||||
"charset type",
|
||||
ObCharset::charset_name(cs_type),
|
||||
"collation type",
|
||||
ObCharset::collation_name(collation_type));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (stmt.is_set_names()) {
|
||||
// SET NAMES
|
||||
ObCollationType cs_coll_type = ObCharset::get_default_collation(ObCharset::charset_type(charset));
|
||||
ObCollationType coll_type = ObCharset::collation_type(collation);
|
||||
if (CS_TYPE_INVALID == cs_coll_type || CS_TYPE_INVALID == coll_type) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "cs coll type or coll type is invalid", K(ret), K(cs_coll_type), K(coll_type));
|
||||
} else if (OB_FAIL(session->update_sys_variable(
|
||||
SYS_VAR_CHARACTER_SET_CLIENT, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(
|
||||
SYS_VAR_CHARACTER_SET_RESULTS, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(
|
||||
SYS_VAR_CHARACTER_SET_CONNECTION, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(
|
||||
session->update_sys_variable(SYS_VAR_COLLATION_CONNECTION, static_cast<int64_t>(coll_type)))) {
|
||||
SQL_ENG_LOG(WARN, "failed to update sys var", K(ret));
|
||||
}
|
||||
} else {
|
||||
// SET CHARACTER SET
|
||||
ObObj database_charset;
|
||||
ObObj database_collation;
|
||||
ObCollationType cs_coll_type = ObCharset::get_default_collation(ObCharset::charset_type(charset));
|
||||
if (OB_FAIL(session->get_sys_variable(SYS_VAR_CHARACTER_SET_DATABASE, database_charset))) {
|
||||
} else if (OB_FAIL(session->get_sys_variable(SYS_VAR_COLLATION_DATABASE, database_collation))) {
|
||||
} else {
|
||||
ObCollationType collation_connection = static_cast<ObCollationType>(database_collation.get_int());
|
||||
ObCharsetType charset_connection = ObCharset::charset_type_by_coll(collation_connection);
|
||||
if (!ObCharset::is_valid_connection_collation(collation_connection)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
SQL_ENG_LOG(WARN,
|
||||
"connection collation type not supported",
|
||||
"charset type",
|
||||
ObCharset::charset_name(charset_connection),
|
||||
"collation type",
|
||||
ObCharset::collation_name(collation_connection));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(
|
||||
session->update_sys_variable(SYS_VAR_CHARACTER_SET_CLIENT, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_EXE_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(
|
||||
SYS_VAR_CHARACTER_SET_RESULTS, static_cast<int64_t>(cs_coll_type)))) {
|
||||
SQL_EXE_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(SYS_VAR_CHARACTER_SET_CONNECTION, database_charset))) {
|
||||
SQL_EXE_LOG(WARN, "failed to update sys var", K(ret));
|
||||
} else if (OB_FAIL(session->update_sys_variable(SYS_VAR_COLLATION_CONNECTION, database_collation))) {
|
||||
SQL_EXE_LOG(WARN, "failed to update sys var", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSetNamesExecutor::get_global_sys_var_character_set_client(
|
||||
ObExecContext& ctx, ObString& character_set_client) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
ObIAllocator& allocator = ctx.get_allocator();
|
||||
ObSchemaGetterGuard schema_guard;
|
||||
const ObSysVarSchema* var_schema = NULL;
|
||||
ObObj value;
|
||||
if (NULL == (session = ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "session is NULL", K(ret), K(ctx));
|
||||
} else if (OB_ISNULL(GCTX.schema_service_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "schema service is null");
|
||||
} else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(session->get_effective_tenant_id(), schema_guard))) {
|
||||
SQL_ENG_LOG(WARN, "get schema guard failed", K(ret));
|
||||
} else if (OB_FAIL(schema_guard.get_tenant_system_variable(
|
||||
session->get_effective_tenant_id(), SYS_VAR_CHARACTER_SET_CLIENT, var_schema))) {
|
||||
SQL_ENG_LOG(WARN, "get tenant system variable failed", K(ret));
|
||||
} else if (OB_ISNULL(var_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "var_schema is null");
|
||||
} else if (OB_FAIL(var_schema->get_value(&allocator, ObBasicSessionInfo::create_dtc_params(session), value))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "get value from var_schema failed", K(ret), K(*var_schema));
|
||||
} else if (ObIntType != value.get_type()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(ERROR, "sys var character_set_client's type must be ObIntType", K(ret), K(value));
|
||||
} else {
|
||||
ObCollationType coll_type = static_cast<ObCollationType>(value.get_int());
|
||||
if (!ObCharset::is_valid_collation(coll_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "invalid collation type", K(ret), K(coll_type));
|
||||
} else {
|
||||
const char* cs_name_ptr = ObCharset::charset_name(coll_type);
|
||||
character_set_client = ObString(cs_name_ptr);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
42
src/sql/engine/cmd/ob_set_names_executor.h
Normal file
42
src/sql/engine/cmd/ob_set_names_executor.h
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef _OB_SET_NAMES_EXECUTOR_H
|
||||
#define _OB_SET_NAMES_EXECUTOR_H 1
|
||||
#include "sql/resolver/cmd/ob_set_names_stmt.h"
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObSetNamesExecutor {
|
||||
public:
|
||||
ObSetNamesExecutor()
|
||||
{}
|
||||
virtual ~ObSetNamesExecutor()
|
||||
{}
|
||||
|
||||
int execute(ObExecContext& ctx, ObSetNamesStmt& stmt);
|
||||
|
||||
private:
|
||||
int get_global_sys_var_character_set_client(ObExecContext& ctx, common::ObString& character_set_client) const;
|
||||
|
||||
private:
|
||||
// disallow copy
|
||||
DISALLOW_COPY_AND_ASSIGN(ObSetNamesExecutor);
|
||||
// function members
|
||||
private:
|
||||
// data members
|
||||
};
|
||||
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
|
||||
#endif /* _OB_SET_NAMES_EXECUTOR_H */
|
||||
122
src/sql/engine/cmd/ob_set_password_executor.cpp
Normal file
122
src/sql/engine/cmd/ob_set_password_executor.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/engine/cmd/ob_set_password_executor.h"
|
||||
#include "lib/string/ob_sql_string.h"
|
||||
#include "lib/encrypt/ob_encrypted_helper.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
#include "sql/resolver/dcl/ob_set_password_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/engine/cmd/ob_user_cmd_executor.h"
|
||||
|
||||
namespace oceanbase {
|
||||
|
||||
using namespace common;
|
||||
using namespace obrpc;
|
||||
using namespace share;
|
||||
using namespace share::schema;
|
||||
namespace sql {
|
||||
|
||||
ObSetPasswordExecutor::ObSetPasswordExecutor()
|
||||
{}
|
||||
|
||||
ObSetPasswordExecutor::~ObSetPasswordExecutor()
|
||||
{}
|
||||
|
||||
int ObSetPasswordExecutor::execute(ObExecContext& ctx, ObSetPasswordStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const uint64_t tenant_id = stmt.get_tenant_id();
|
||||
const common::ObStrings* user_passwd = NULL;
|
||||
const int64_t FIX_MEMBER_CNT = 7;
|
||||
if (OB_ISNULL(session = ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session is NULL", K(ret));
|
||||
} else if (OB_UNLIKELY(OB_INVALID_ID == tenant_id)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("tenant is invalid", K(ret));
|
||||
} else if (OB_ISNULL(user_passwd = stmt.get_user_password())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("user_passwd is null", K(ret));
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("task_exec_ctx is null", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("common_rpc_proxy is null", K(ret));
|
||||
} else if (OB_UNLIKELY(FIX_MEMBER_CNT != user_passwd->count())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
;
|
||||
LOG_WARN("invalid set pwd stmt, wrong user passwd count", K(ret));
|
||||
} else {
|
||||
ObString user_name;
|
||||
ObString host_name;
|
||||
ObString passwd;
|
||||
ObString ssl_type;
|
||||
ObString ssl_cipher;
|
||||
ObString x509_issuer;
|
||||
ObString x509_subject;
|
||||
ObSSLType ssl_type_enum = ObSSLType::SSL_TYPE_NOT_SPECIFIED;
|
||||
|
||||
if (OB_FAIL(user_passwd->get_string(0, user_name))) {
|
||||
LOG_WARN("Get user name failed", K(ret));
|
||||
} else if (OB_FAIL(user_passwd->get_string(1, host_name))) {
|
||||
LOG_WARN("Get passwd failed", K(ret));
|
||||
} else if (OB_FAIL(user_passwd->get_string(2, passwd))) {
|
||||
LOG_WARN("Get passwd failed", K(ret));
|
||||
} else if (OB_FAIL(user_passwd->get_string(3, ssl_type))) {
|
||||
LOG_WARN("Get string from ObStrings error", K(ret));
|
||||
} else if (OB_FAIL(user_passwd->get_string(4, ssl_cipher))) {
|
||||
LOG_WARN("Get string from ObStrings error", K(ret));
|
||||
} else if (OB_FAIL(user_passwd->get_string(5, x509_issuer))) {
|
||||
LOG_WARN("Get string from ObStrings error", K(ret));
|
||||
} else if (OB_FAIL(user_passwd->get_string(6, x509_subject))) {
|
||||
LOG_WARN("Get string from ObStrings error", K(ret));
|
||||
} else if (OB_UNLIKELY(ObSSLType::SSL_TYPE_MAX == (ssl_type_enum = get_ssl_type_from_string(ssl_type)))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("known ssl_type", K(ssl_type), K(ret));
|
||||
} else {
|
||||
char enc_buf[ENC_BUF_LEN] = {0};
|
||||
ObSetPasswdArg arg;
|
||||
arg.tenant_id_ = tenant_id;
|
||||
arg.user_ = user_name;
|
||||
arg.host_ = host_name;
|
||||
arg.ssl_type_ = ssl_type_enum;
|
||||
arg.ssl_cipher_ = ssl_cipher;
|
||||
arg.x509_issuer_ = x509_issuer;
|
||||
arg.x509_subject_ = x509_subject;
|
||||
arg.exec_tenant_id_ = tenant_id;
|
||||
if (stmt.get_need_enc()) {
|
||||
if (OB_FAIL(ObCreateUserExecutor::encrypt_passwd(passwd, arg.passwd_, enc_buf, ENC_BUF_LEN))) {
|
||||
LOG_WARN("Encrypt passwd failed", K(ret));
|
||||
}
|
||||
} else {
|
||||
arg.passwd_ = passwd;
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_FAIL(common_rpc_proxy->set_passwd(arg))) {
|
||||
LOG_WARN("Set password failed", K(ret));
|
||||
} else if (0 == user_name.case_compare(session->get_user_name())) {
|
||||
session->set_password_expired(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
39
src/sql/engine/cmd/ob_set_password_executor.h
Normal file
39
src/sql/engine/cmd/ob_set_password_executor.h
Normal file
@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_SET_PASSWORD_EXECUTOR_
|
||||
#define OCEANBASE_SQL_SET_PASSWORD_EXECUTOR_
|
||||
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
class ObString;
|
||||
class ObSqlString;
|
||||
} // namespace common
|
||||
namespace obrpc {
|
||||
class ObCommonRpcProxy;
|
||||
}
|
||||
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObSetPasswordStmt;
|
||||
|
||||
class ObSetPasswordExecutor {
|
||||
public:
|
||||
ObSetPasswordExecutor();
|
||||
virtual ~ObSetPasswordExecutor();
|
||||
int execute(ObExecContext& ctx, ObSetPasswordStmt& stmt);
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif /* __OB_SQL_SET_PASSWORD_EXECUTOR_H__ */
|
||||
//// end of header file
|
||||
84
src/sql/engine/cmd/ob_synonym_executor.cpp
Normal file
84
src/sql/engine/cmd/ob_synonym_executor.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/engine/cmd/ob_synonym_executor.h"
|
||||
#include "share/object/ob_obj_cast.h"
|
||||
#include "lib/mysqlclient/ob_mysql_proxy.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "sql/resolver/ddl/ob_create_synonym_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_drop_synonym_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/engine/ob_physical_plan.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/code_generator/ob_expr_generator_impl.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace share::schema;
|
||||
namespace sql {
|
||||
|
||||
int ObCreateSynonymExecutor::execute(ObExecContext& ctx, ObCreateSynonymStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObCreateSynonymArg& create_synonym_arg = stmt.get_create_synonym_arg();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObCreateSynonymArg&>(create_synonym_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed", K(ret));
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->create_synonym(create_synonym_arg))) {
|
||||
LOG_WARN("rpc proxy create synonym failed", K(ret), "dst", common_rpc_proxy->get_server());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDropSynonymExecutor::execute(ObExecContext& ctx, ObDropSynonymStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObDropSynonymArg& drop_synonym_arg = stmt.get_drop_synonym_arg();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObDropSynonymArg&>(drop_synonym_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed", K(ret));
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->drop_synonym(drop_synonym_arg))) {
|
||||
LOG_WARN("rpc proxy drop synonym failed", K(ret), "dst", common_rpc_proxy->get_server());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
58
src/sql/engine/cmd/ob_synonym_executor.h
Normal file
58
src/sql/engine/cmd/ob_synonym_executor.h
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_OB_SYNONYM_EXECUTOR_
|
||||
#define OCEANBASE_SQL_OB_SYNONYM_EXECUTOR_
|
||||
#include "common/object/ob_object.h"
|
||||
#include "lib/container/ob_se_array.h"
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
class ObIAllocator;
|
||||
class ObExprCtx;
|
||||
namespace sqlclient {
|
||||
class ObMySQLProxy;
|
||||
}
|
||||
} // namespace common
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObRawExpr;
|
||||
class ObCreateSynonymStmt;
|
||||
class ObCreateSynonymExecutor {
|
||||
public:
|
||||
const static int OB_DEFAULT_ARRAY_SIZE = 16;
|
||||
ObCreateSynonymExecutor()
|
||||
{}
|
||||
virtual ~ObCreateSynonymExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObCreateSynonymStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObCreateSynonymExecutor);
|
||||
};
|
||||
|
||||
class ObDropSynonymStmt;
|
||||
class ObDropSynonymExecutor {
|
||||
public:
|
||||
ObDropSynonymExecutor()
|
||||
{}
|
||||
virtual ~ObDropSynonymExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObDropSynonymStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObDropSynonymExecutor);
|
||||
};
|
||||
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
|
||||
#endif // OCEANBASE_SQL_OB_SYNONYM_EXECUTOR_
|
||||
2257
src/sql/engine/cmd/ob_table_executor.cpp
Normal file
2257
src/sql/engine/cmd/ob_table_executor.cpp
Normal file
File diff suppressed because it is too large
Load Diff
311
src/sql/engine/cmd/ob_table_executor.h
Normal file
311
src/sql/engine/cmd/ob_table_executor.h
Normal file
@ -0,0 +1,311 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_OB_TABLE_EXECUTOR_
|
||||
#define OCEANBASE_SQL_OB_TABLE_EXECUTOR_
|
||||
#include "common/object/ob_object.h"
|
||||
#include "lib/container/ob_se_array.h"
|
||||
#include "common/sql_mode/ob_sql_mode.h"
|
||||
#include "lib/string/ob_sql_string.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
namespace oceanbase {
|
||||
namespace share {
|
||||
namespace schema {
|
||||
class ObPartition;
|
||||
class ObSubPartition;
|
||||
class ObBasePartition;
|
||||
class ObMultiVersionSchemaService;
|
||||
} // namespace schema
|
||||
} // namespace share
|
||||
namespace obrpc {
|
||||
class ObAlterTableArg;
|
||||
}
|
||||
namespace common {
|
||||
class ObIAllocator;
|
||||
class ObExprCtx;
|
||||
class ObNewRow;
|
||||
namespace sqlclient {
|
||||
class ObMySQLProxy;
|
||||
}
|
||||
} // namespace common
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObRawExpr;
|
||||
class ObCreateTableStmt;
|
||||
class ObTableStmt;
|
||||
|
||||
class ObTableExecutorUtils {
|
||||
public:
|
||||
static int get_first_stmt(
|
||||
const common::ObString& stmt, common::ObString& first_stmt, ObSQLMode sql_mode = DEFAULT_OCEANBASE_MODE);
|
||||
};
|
||||
|
||||
class ObCreateTableExecutor {
|
||||
public:
|
||||
ObCreateTableExecutor();
|
||||
virtual ~ObCreateTableExecutor();
|
||||
int execute(ObExecContext& ctx, ObCreateTableStmt& stmt);
|
||||
int set_index_arg_list(ObExecContext& ctx, ObCreateTableStmt& stmt);
|
||||
int execute_ctas(ObExecContext& ctx, ObCreateTableStmt& stmt, obrpc::ObCommonRpcProxy* common_rpc_proxy);
|
||||
|
||||
private:
|
||||
int prepare_ins_arg(ObCreateTableStmt& stmt, const ObSQLSessionInfo* my_session, ObSqlString& ins_sql);
|
||||
int prepare_alter_arg(
|
||||
ObCreateTableStmt& stmt, const ObSQLSessionInfo* my_session, obrpc::ObAlterTableArg& alter_table_arg);
|
||||
int prepare_drop_arg(const ObCreateTableStmt& stmt, const ObSQLSessionInfo* my_session,
|
||||
obrpc::ObTableItem& table_item, obrpc::ObDropTableArg& drop_table_arg);
|
||||
};
|
||||
|
||||
class ObAlterTableStmt;
|
||||
class ObAlterTableExecutor {
|
||||
public:
|
||||
ObAlterTableExecutor();
|
||||
virtual ~ObAlterTableExecutor();
|
||||
int execute(ObExecContext& ctx, ObAlterTableStmt& stmt);
|
||||
|
||||
private:
|
||||
struct PartitionServer {
|
||||
PartitionServer() : pkey_(), server_()
|
||||
{}
|
||||
void reset()
|
||||
{
|
||||
pkey_.reset();
|
||||
server_.reset();
|
||||
}
|
||||
TO_STRING_KV(K(pkey_), K(server_));
|
||||
int set_server(const common::ObAddr& server)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (!server.is_valid()) {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
RS_LOG(WARN, "invalid argument", K(ret), K(server));
|
||||
} else {
|
||||
server_ = server;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int set_partition_key(const common::ObPartitionKey& pkey)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (!pkey.is_valid()) {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
RS_LOG(WARN, "invalid argument", K(ret), K(pkey));
|
||||
} else {
|
||||
pkey_ = pkey;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int set(const common::ObAddr& server, common::ObPartitionKey& pkey)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (!server.is_valid() || !pkey.is_valid()) {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
RS_LOG(WARN, "invalid argument", K(ret), K(server), K(pkey));
|
||||
} else {
|
||||
server_ = server;
|
||||
pkey_ = pkey;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int set(
|
||||
const common::ObAddr& server, const uint64_t table_id, const int64_t partition_id, const int64_t partition_cnt)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (!server.is_valid()) {
|
||||
ret = common::OB_INVALID_ARGUMENT;
|
||||
RS_LOG(WARN, "invalid argument", K(ret), K(server));
|
||||
} else if (OB_FAIL(pkey_.init(table_id, partition_id, partition_cnt))) {
|
||||
RS_LOG(WARN, "fail to init pkey", K(ret), K(table_id), K(partition_id), K(partition_cnt));
|
||||
} else {
|
||||
server_ = server;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
common::ObPartitionKey pkey_;
|
||||
common::ObAddr server_;
|
||||
};
|
||||
static const int64_t TIME_INTERVAL_PER_PART_US = 50 * 1000; // 50ms
|
||||
static const int64_t MAX_WAIT_CHECK_SCHEMA_VERSION_INTERVAL_US = 120LL * 1000000LL; // 120s
|
||||
static const int64_t MIN_WAIT_CHECK_SCHEMA_VERSION_INTERVAL_US = 20LL * 1000000LL; // 20s
|
||||
static const int64_t WAIT_US = 500 * 1000; // 500ms
|
||||
static const int64_t GET_ASSOCIATED_SNAPSHOT_TIMEOUT = 9000000LL; // 9s
|
||||
|
||||
int alter_table_rpc_v1(obrpc::ObAlterTableArg& alter_table_arg, obrpc::ObAlterTableRes& res,
|
||||
common::ObIAllocator& allocator, obrpc::ObCommonRpcProxy* common_rpc_proxy, ObSQLSessionInfo* my_session,
|
||||
const bool is_sync_ddl_user);
|
||||
|
||||
int alter_table_rpc_v2(obrpc::ObAlterTableArg& alter_table_arg, obrpc::ObAlterTableRes& res,
|
||||
common::ObIAllocator& allocator, obrpc::ObCommonRpcProxy* common_rpc_proxy, ObSQLSessionInfo* my_session,
|
||||
const bool is_sync_ddl_user);
|
||||
|
||||
int set_alter_col_nullable_ddl_stmt_str(obrpc::ObAlterTableArg& alter_table_arg, common::ObIAllocator& allocator);
|
||||
|
||||
int set_drop_constraint_ddl_stmt_str(obrpc::ObAlterTableArg& alter_table_arg, common::ObIAllocator& allocator);
|
||||
|
||||
int set_alter_constraint_ddl_stmt_str_for_check(
|
||||
obrpc::ObAlterTableArg& alter_table_arg, common::ObIAllocator& allocator);
|
||||
|
||||
int set_alter_constraint_ddl_stmt_str_for_fk(
|
||||
obrpc::ObAlterTableArg& alter_table_arg, common::ObIAllocator& allocator);
|
||||
|
||||
int init_build_snapshot_ctx(const common::ObIArray<PartitionServer>& partition_leader_array,
|
||||
common::ObIArray<int64_t>& invalid_snapshot_id_array, common::ObIArray<int64_t>& snapshot_array);
|
||||
|
||||
int generate_original_table_partition_leader_array(ObExecContext& ctx,
|
||||
share::schema::ObSchemaGetterGuard& schema_guard, const share::schema::ObTableSchema* data_schema,
|
||||
common::ObIArray<PartitionServer>& partition_leader_array);
|
||||
|
||||
int update_partition_leader_array(common::ObIArray<PartitionServer>& partition_leader_array,
|
||||
const common::ObIArray<int>& ret_code_array, const common::ObIArray<int64_t>& invalid_snapshot_id_array);
|
||||
|
||||
int pick_build_snapshot(const common::ObIArray<int64_t>& snapshot_array, int64_t& snapshot);
|
||||
|
||||
template <typename PROXY>
|
||||
int update_build_snapshot_ctx(PROXY& proxy, const common::ObIArray<int>& ret_code_array,
|
||||
common::ObIArray<int64_t>& invalid_snapshot_id_array, common::ObIArray<int64_t>& snapshot_array);
|
||||
|
||||
template <typename PROXY, typename ARG>
|
||||
int do_get_associated_snapshot(PROXY& rpc_proxy, ARG& rpc_arg, int64_t schema_version,
|
||||
const share::schema::ObTableSchema* data_schema, common::ObIArray<PartitionServer>& partition_leader_array,
|
||||
int64_t& snapshot);
|
||||
|
||||
int get_constraint_check_snapshot(ObExecContext& ctx, int64_t schema_version,
|
||||
share::schema::ObSchemaGetterGuard& schema_guard, const uint64_t table_id, int64_t& snapshot);
|
||||
|
||||
int check_data_validity_for_check_by_inner_sql(const share::schema::AlterTableSchema& alter_table_schema,
|
||||
ObCommonSqlProxy* sql_proxy, const ObString& check_expr_str, bool& is_data_valid);
|
||||
|
||||
int check_check_constraint_data_validity(ObExecContext& ctx, const obrpc::ObAlterTableArg& alter_table_arg,
|
||||
ObCommonSqlProxy* sql_proxy, int64_t schema_version, const ObString& check_expr_str, bool& is_data_valid);
|
||||
|
||||
int check_data_validity_for_fk_by_inner_sql(const share::schema::AlterTableSchema& alter_table_schema,
|
||||
const obrpc::ObCreateForeignKeyArg& fk_arg, ObCommonSqlProxy* sql_proxy, bool& is_data_valid);
|
||||
|
||||
int check_fk_constraint_data_validity(ObExecContext& ctx, const obrpc::ObAlterTableArg& alter_table_arg,
|
||||
ObCommonSqlProxy* sql_proxy, int64_t schema_version, bool& is_data_valid);
|
||||
|
||||
int check_alter_partition(ObExecContext& ctx, ObAlterTableStmt& stmt, const obrpc::ObAlterTableArg& arg);
|
||||
|
||||
int set_index_arg_list(ObExecContext& ctx, ObAlterTableStmt& stmt);
|
||||
|
||||
int refresh_schema_for_table(const uint64_t tenant_id);
|
||||
|
||||
private:
|
||||
// DISALLOW_COPY_AND_ASSIGN(ObAlterTableExecutor);
|
||||
};
|
||||
|
||||
class ObDropTableStmt;
|
||||
class ObDropTableExecutor {
|
||||
public:
|
||||
ObDropTableExecutor();
|
||||
virtual ~ObDropTableExecutor();
|
||||
int execute(ObExecContext& ctx, ObDropTableStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObRenameTableStmt;
|
||||
class ObRenameTableExecutor {
|
||||
public:
|
||||
ObRenameTableExecutor();
|
||||
virtual ~ObRenameTableExecutor();
|
||||
int execute(ObExecContext& ctx, ObRenameTableStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObTruncateTableStmt;
|
||||
class ObTruncateTableExecutor {
|
||||
public:
|
||||
ObTruncateTableExecutor();
|
||||
virtual ~ObTruncateTableExecutor();
|
||||
int execute(ObExecContext& ctx, ObTruncateTableStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObCreateTableLikeStmt;
|
||||
class ObCreateTableLikeExecutor {
|
||||
public:
|
||||
ObCreateTableLikeExecutor();
|
||||
virtual ~ObCreateTableLikeExecutor();
|
||||
int execute(ObExecContext& ctx, ObCreateTableLikeStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObFlashBackTableFromRecyclebinStmt;
|
||||
class ObFlashBackTableFromRecyclebinExecutor {
|
||||
public:
|
||||
ObFlashBackTableFromRecyclebinExecutor()
|
||||
{}
|
||||
virtual ~ObFlashBackTableFromRecyclebinExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObFlashBackTableFromRecyclebinStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObFlashBackTableToScnStmt;
|
||||
class ObFlashBackTableToScnExecutor {
|
||||
public:
|
||||
ObFlashBackTableToScnExecutor()
|
||||
{}
|
||||
virtual ~ObFlashBackTableToScnExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObFlashBackTableToScnStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObPurgeTableStmt;
|
||||
class ObPurgeTableExecutor {
|
||||
public:
|
||||
ObPurgeTableExecutor()
|
||||
{}
|
||||
virtual ~ObPurgeTableExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObPurgeTableStmt& stmt);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
class ObOptimizeTableStmt;
|
||||
class ObOptimizeTableExecutor {
|
||||
public:
|
||||
ObOptimizeTableExecutor() = default;
|
||||
virtual ~ObOptimizeTableExecutor() = default;
|
||||
int execute(ObExecContext& ctx, ObOptimizeTableStmt& stmt);
|
||||
};
|
||||
|
||||
class ObOptimizeTenantStmt;
|
||||
class ObOptimizeTenantExecutor {
|
||||
public:
|
||||
ObOptimizeTenantExecutor() = default;
|
||||
virtual ~ObOptimizeTenantExecutor() = default;
|
||||
int execute(ObExecContext& ctx, ObOptimizeTenantStmt& stmt);
|
||||
static int optimize_tenant(const obrpc::ObOptimizeTenantArg& arg, const uint64_t tenant_id,
|
||||
share::schema::ObMultiVersionSchemaService& schema_service, obrpc::ObCommonRpcProxy* common_rpc_proxy);
|
||||
};
|
||||
|
||||
class ObOptimizeAllStmt;
|
||||
class ObOptimizeAllExecutor {
|
||||
public:
|
||||
ObOptimizeAllExecutor() = default;
|
||||
virtual ~ObOptimizeAllExecutor() = default;
|
||||
int execute(ObExecContext& ctx, ObOptimizeAllStmt& stmt);
|
||||
};
|
||||
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
|
||||
#endif // OCEANBASE_SQL_OB_TABLE_EXECUTOR_
|
||||
197
src/sql/engine/cmd/ob_tablegroup_executor.cpp
Normal file
197
src/sql/engine/cmd/ob_tablegroup_executor.cpp
Normal file
@ -0,0 +1,197 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "share/object/ob_obj_cast.h"
|
||||
#include "sql/engine/cmd/ob_tablegroup_executor.h"
|
||||
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/resolver/ddl/ob_create_tablegroup_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_alter_tablegroup_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_drop_tablegroup_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/code_generator/ob_expr_generator_impl.h"
|
||||
#include "sql/engine/cmd/ob_partition_executor_utils.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace share::schema;
|
||||
namespace sql {
|
||||
int ObCreateTablegroupExecutor::execute(ObExecContext& ctx, ObCreateTablegroupStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
obrpc::ObRpcOpts rpc_opt;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
obrpc::ObCreateTablegroupArg& create_tablegroup_arg = stmt.get_create_tablegroup_arg();
|
||||
|
||||
ObTablegroupSchema& tablegroup_schema = create_tablegroup_arg.tablegroup_schema_;
|
||||
tablegroup_schema.set_part_func_expr_num(stmt.get_part_func_expr_num());
|
||||
tablegroup_schema.set_sub_part_func_expr_num(stmt.get_sub_part_func_expr_num());
|
||||
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObCreateTablegroupArg&>(create_tablegroup_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_FAIL(ObPartitionExecutorUtils::calc_values_exprs(ctx, stmt))) {
|
||||
LOG_WARN("compare range parition expr fail", K(ret));
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else {
|
||||
obrpc::UInt64 tablegroup_id(0);
|
||||
if (OB_FAIL(common_rpc_proxy->create_tablegroup(create_tablegroup_arg, tablegroup_id))) {
|
||||
LOG_WARN("rpc proxy create tablegroup failed", K(ret));
|
||||
}
|
||||
}
|
||||
LOG_INFO("finish execute create tablegroup.", K(stmt), K(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDropTablegroupExecutor::execute(ObExecContext& ctx, ObDropTablegroupStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
obrpc::ObRpcOpts rpc_opt;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObDropTablegroupArg& drop_tablegroup_arg = stmt.get_drop_tablegroup_arg();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObDropTablegroupArg&>(drop_tablegroup_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->drop_tablegroup(drop_tablegroup_arg))) {
|
||||
LOG_WARN("rpc proxy drop tablegroup failed", K(ret));
|
||||
}
|
||||
LOG_INFO("finish execute drop tablegroup.", K(stmt), K(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObAlterTablegroupExecutor::execute(ObExecContext& ctx, ObAlterTablegroupStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
obrpc::ObAlterTablegroupArg& alter_tablegroup_arg = stmt.get_alter_tablegroup_arg();
|
||||
alter_tablegroup_arg.alter_tablegroup_schema_.set_part_func_expr_num(stmt.get_part_func_expr_num());
|
||||
alter_tablegroup_arg.alter_tablegroup_schema_.set_sub_part_func_expr_num(stmt.get_sub_part_func_expr_num());
|
||||
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObAlterTablegroupArg&>(alter_tablegroup_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(check_alter_partition(ctx, stmt, alter_tablegroup_arg))) {
|
||||
LOG_WARN("check alter partition failed", K(ret));
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->alter_tablegroup(alter_tablegroup_arg))) {
|
||||
LOG_WARN(
|
||||
"rpc proxy alter table group failed", "dst", common_rpc_proxy->get_server(), K(ret), K(alter_tablegroup_arg));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObAlterTablegroupExecutor::check_alter_partition(
|
||||
ObExecContext& ctx, ObAlterTablegroupStmt& stmt, const obrpc::ObAlterTablegroupArg& arg)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (arg.is_alter_partitions()) {
|
||||
const ObTablegroupSchema& tablegroup_schema = arg.alter_tablegroup_schema_;
|
||||
if (arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::ADD_PARTITION) ||
|
||||
arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::PARTITIONED_TABLE) ||
|
||||
arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::REORGANIZE_PARTITION) ||
|
||||
arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::SPLIT_PARTITION)) {
|
||||
ObPartition** partition_array = tablegroup_schema.get_part_array();
|
||||
int64_t real_part_num = tablegroup_schema.get_partition_num();
|
||||
const int64_t fun_expr_num = stmt.get_part_func_expr_num();
|
||||
if (arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::SPLIT_PARTITION)) {
|
||||
real_part_num = tablegroup_schema.get_part_option().get_part_num();
|
||||
}
|
||||
if (tablegroup_schema.is_range_part()) {
|
||||
ObSEArray<ObObj, 8> range_partition_obj;
|
||||
ObIArray<ObRawExpr*>& range_values_exprs = stmt.get_part_values_exprs();
|
||||
if (OB_ISNULL(partition_array)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("partition_array is NULL", K(ret));
|
||||
} else if (OB_FAIL(ObPartitionExecutorUtils::cast_range_expr_to_obj(ctx,
|
||||
range_values_exprs,
|
||||
fun_expr_num,
|
||||
stmt::T_ALTER_TABLEGROUP,
|
||||
false, // is_subpart
|
||||
real_part_num,
|
||||
partition_array,
|
||||
NULL,
|
||||
range_partition_obj))) {
|
||||
LOG_WARN("partition_array is NULL", K(ret));
|
||||
}
|
||||
} else if (tablegroup_schema.is_list_part()) {
|
||||
if (OB_ISNULL(partition_array)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("partition_array is NULL", K(ret));
|
||||
} else if (OB_FAIL(ObPartitionExecutorUtils::cast_list_expr_to_obj(ctx, stmt, false, partition_array, NULL))) {
|
||||
LOG_WARN("failed cast list to expr", K(ret));
|
||||
}
|
||||
} else if (!arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::PARTITIONED_TABLE)) {
|
||||
ret = OB_ERR_ONLY_ON_RANGE_LIST_PARTITION;
|
||||
LOG_WARN("unexpected partition type",
|
||||
K(ret),
|
||||
"partition type",
|
||||
tablegroup_schema.get_part_option().get_part_func_type());
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::SPLIT_PARTITION)) {
|
||||
const_cast<ObTablegroupSchema&>(tablegroup_schema)
|
||||
.get_part_option()
|
||||
.set_part_num(tablegroup_schema.get_partition_num());
|
||||
}
|
||||
} else if (arg.alter_option_bitset_.has_member(obrpc::ObAlterTablegroupArg::DROP_PARTITION)) {
|
||||
// do-nothing
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("no operation", K(arg), K(ret));
|
||||
}
|
||||
LOG_DEBUG("dump table schema", K(tablegroup_schema));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
65
src/sql/engine/cmd/ob_tablegroup_executor.h
Normal file
65
src/sql/engine/cmd/ob_tablegroup_executor.h
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_OB_TABLEGROUP_EXECUTOR_
|
||||
#define OCEANBASE_SQL_OB_TABLEGROUP_EXECUTOR_
|
||||
#include "share/ob_define.h"
|
||||
#include "common/object/ob_object.h"
|
||||
#include "lib/container/ob_se_array.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
namespace oceanbase {
|
||||
namespace share {
|
||||
namespace schema {
|
||||
class ObPartition;
|
||||
class ObSubPartition;
|
||||
} // namespace schema
|
||||
} // namespace share
|
||||
namespace sql {
|
||||
class ObRawExpr;
|
||||
|
||||
#define DEF_SIMPLE_EXECUTOR(name) \
|
||||
class name##Executor { \
|
||||
public: \
|
||||
name##Executor() \
|
||||
{} \
|
||||
virtual ~name##Executor() \
|
||||
{} \
|
||||
int execute(ObExecContext& ctx, name##Stmt& stmt); \
|
||||
\
|
||||
private: \
|
||||
DISALLOW_COPY_AND_ASSIGN(name##Executor); \
|
||||
}
|
||||
|
||||
class ObExecContext;
|
||||
class ObCreateTablegroupStmt;
|
||||
DEF_SIMPLE_EXECUTOR(ObCreateTablegroup);
|
||||
|
||||
class ObDropTablegroupStmt;
|
||||
DEF_SIMPLE_EXECUTOR(ObDropTablegroup);
|
||||
|
||||
class ObAlterTablegroupStmt;
|
||||
class ObAlterTablegroupExecutor {
|
||||
public:
|
||||
ObAlterTablegroupExecutor()
|
||||
{}
|
||||
virtual ~ObAlterTablegroupExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObAlterTablegroupStmt& stmt);
|
||||
|
||||
private:
|
||||
int check_alter_partition(ObExecContext& ctx, ObAlterTablegroupStmt& stmt, const obrpc::ObAlterTablegroupArg& arg);
|
||||
DISALLOW_COPY_AND_ASSIGN(ObAlterTablegroupExecutor);
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif /* OCEANBASE_SQL_OB_TABLEGROUP_EXECUTOR_ */
|
||||
123
src/sql/engine/cmd/ob_tcl_executor.cpp
Normal file
123
src/sql/engine/cmd/ob_tcl_executor.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/engine/cmd/ob_tcl_executor.h"
|
||||
|
||||
#include "lib/encrypt/ob_encrypted_helper.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "sql/ob_sql_trans_control.h"
|
||||
#include "sql/resolver/tcl/ob_end_trans_stmt.h"
|
||||
#include "sql/resolver/tcl/ob_start_trans_stmt.h"
|
||||
#include "sql/resolver/tcl/ob_savepoint_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace share::schema;
|
||||
namespace sql {
|
||||
|
||||
int ObEndTransExecutor::execute(ObExecContext& ctx, ObEndTransStmt& stmt)
|
||||
{
|
||||
return end_trans(ctx, stmt);
|
||||
}
|
||||
|
||||
int ObEndTransExecutor::end_trans(ObExecContext& ctx, ObEndTransStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* my_session = GET_MY_SESSION(ctx);
|
||||
if (OB_ISNULL(my_session)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("session ptr is null", K(ret));
|
||||
} else if (my_session->is_in_transaction() && my_session->get_trans_desc().is_xa_local_trans()) {
|
||||
transaction::ObXATransID xid = my_session->get_trans_desc().get_xid();
|
||||
if (stmt.get_is_rollback()) {
|
||||
// Rollback can be executed in the xa transaction,
|
||||
// the role is to roll back all modifications, but does not end the xa transaction
|
||||
} else {
|
||||
// commit is prohibited in xa transaction
|
||||
ret = OB_TRANS_XA_ERR_COMMIT;
|
||||
LOG_WARN("COMMIT is not allowed in a xa trans", K(ret), K(xid));
|
||||
}
|
||||
ctx.set_need_disconnect(false);
|
||||
} else if (OB_FAIL(ObSqlTransControl::explicit_end_trans(ctx, stmt.get_is_rollback()))) {
|
||||
LOG_WARN("fail end trans", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObStartTransExecutor::execute(ObExecContext& ctx, ObStartTransStmt& stmt)
|
||||
{
|
||||
return start_trans(ctx, stmt);
|
||||
}
|
||||
|
||||
int ObStartTransExecutor::start_trans(ObExecContext& ctx, ObStartTransStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(ObSqlTransControl::explicit_start_trans(ctx, stmt.get_read_only()))) {
|
||||
LOG_WARN("fail start trans", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateSavePointExecutor::execute(ObExecContext& ctx, ObCreateSavePointStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = GET_MY_SESSION(ctx);
|
||||
if (OB_ISNULL(session)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid param", K(ret), K(session));
|
||||
} else if (!session->is_in_transaction() && !session->get_local_autocommit() &&
|
||||
OB_FAIL(ObSqlTransControl::explicit_start_trans(ctx, session->get_tx_read_only()))) {
|
||||
LOG_WARN("fail start trans", K(ret));
|
||||
} else if (OB_FAIL(ObSqlTransControl::create_savepoint(ctx, stmt.get_sp_name()))) {
|
||||
LOG_WARN("fail create savepoint", K(ret), K(stmt.get_sp_name()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRollbackSavePointExecutor::execute(ObExecContext& ctx, ObRollbackSavePointStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = GET_MY_SESSION(ctx);
|
||||
if (OB_ISNULL(session)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid param", K(ret), K(session));
|
||||
} else if (!session->is_in_transaction()) {
|
||||
ret = OB_SAVEPOINT_NOT_EXIST;
|
||||
LOG_WARN("savepoint is not exist", K(ret), K(stmt.get_sp_name()));
|
||||
} else if (OB_FAIL(ObSqlTransControl::rollback_savepoint(ctx, stmt.get_sp_name()))) {
|
||||
LOG_WARN("fail rollback to savepoint", K(ret), K(stmt.get_sp_name()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObReleaseSavePointExecutor::execute(ObExecContext& ctx, ObReleaseSavePointStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = GET_MY_SESSION(ctx);
|
||||
if (OB_ISNULL(session)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid param", K(ret), K(session));
|
||||
} else if (!session->is_in_transaction()) {
|
||||
ret = OB_SAVEPOINT_NOT_EXIST;
|
||||
LOG_WARN("savepoint is not exist", K(ret), K(stmt.get_sp_name()));
|
||||
} else if (OB_FAIL(ObSqlTransControl::release_savepoint(ctx, stmt.get_sp_name()))) {
|
||||
LOG_WARN("fail release savepoint", K(ret), K(stmt.get_sp_name()));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
90
src/sql/engine/cmd/ob_tcl_executor.h
Normal file
90
src/sql/engine/cmd/ob_tcl_executor.h
Normal file
@ -0,0 +1,90 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCRANBASE_SQL_ENGINE_CMD_OB_TCL_CMD_EXECUTOR_
|
||||
#define OCRANBASE_SQL_ENGINE_CMD_OB_TCL_CMD_EXECUTOR_
|
||||
|
||||
#include "share/ob_define.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObEndTransStmt;
|
||||
class ObEndTransExecutor {
|
||||
public:
|
||||
ObEndTransExecutor()
|
||||
{}
|
||||
virtual ~ObEndTransExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObEndTransStmt& stmt);
|
||||
|
||||
private:
|
||||
int end_trans(ObExecContext& ctx, ObEndTransStmt& stmt);
|
||||
DISALLOW_COPY_AND_ASSIGN(ObEndTransExecutor);
|
||||
};
|
||||
|
||||
class ObStartTransStmt;
|
||||
class ObStartTransExecutor {
|
||||
public:
|
||||
ObStartTransExecutor()
|
||||
{}
|
||||
virtual ~ObStartTransExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObStartTransStmt& stmt);
|
||||
|
||||
private:
|
||||
int start_trans(ObExecContext& ctx, ObStartTransStmt& stmt);
|
||||
DISALLOW_COPY_AND_ASSIGN(ObStartTransExecutor);
|
||||
};
|
||||
|
||||
class ObCreateSavePointStmt;
|
||||
class ObCreateSavePointExecutor {
|
||||
public:
|
||||
ObCreateSavePointExecutor()
|
||||
{}
|
||||
virtual ~ObCreateSavePointExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObCreateSavePointStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObCreateSavePointExecutor);
|
||||
};
|
||||
|
||||
class ObRollbackSavePointStmt;
|
||||
class ObRollbackSavePointExecutor {
|
||||
public:
|
||||
ObRollbackSavePointExecutor()
|
||||
{}
|
||||
virtual ~ObRollbackSavePointExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObRollbackSavePointStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObRollbackSavePointExecutor);
|
||||
};
|
||||
|
||||
class ObReleaseSavePointStmt;
|
||||
class ObReleaseSavePointExecutor {
|
||||
public:
|
||||
ObReleaseSavePointExecutor()
|
||||
{}
|
||||
virtual ~ObReleaseSavePointExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObReleaseSavePointStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObReleaseSavePointExecutor);
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif // OCRANBASE_SQL_ENGINE_CMD_OB_TCL_CMD_EXECUTOR_
|
||||
618
src/sql/engine/cmd/ob_tenant_executor.cpp
Normal file
618
src/sql/engine/cmd/ob_tenant_executor.cpp
Normal file
@ -0,0 +1,618 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/engine/cmd/ob_tenant_executor.h"
|
||||
|
||||
#include "lib/container/ob_se_array_iterator.h"
|
||||
#include "common/sql_mode/ob_sql_mode_utils.h"
|
||||
#include "share/ob_unit_getter.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "share/config/ob_server_config.h"
|
||||
#include "share/schema/ob_schema_getter_guard.h"
|
||||
#include "share/schema/ob_multi_version_schema_service.h"
|
||||
#include "share/ob_get_compat_mode.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/resolver/ddl/ob_create_tenant_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_drop_tenant_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_lock_tenant_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_modify_tenant_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_purge_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/engine/cmd/ob_variable_set_executor.h"
|
||||
#include "sql/code_generator/ob_expr_generator_impl.h"
|
||||
#include "sql/resolver/cmd/ob_create_restore_point_stmt.h"
|
||||
#include "sql/resolver/cmd/ob_drop_restore_point_stmt.h"
|
||||
#include "observer/ob_inner_sql_connection_pool.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace share;
|
||||
using namespace share::schema;
|
||||
namespace sql {
|
||||
int check_sys_var_options(ObExecContext& ctx, const common::ObIArray<ObVariableSetStmt::VariableSetNode>& sys_var_nodes,
|
||||
share::schema::ObTenantSchema& tenant_schema, common::ObIArray<obrpc::ObSysVarIdValue>& sys_var_list);
|
||||
|
||||
int ObCreateTenantExecutor::execute(ObExecContext& ctx, ObCreateTenantStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
obrpc::ObSrvRpcProxy* srv_rpc_proxy = NULL;
|
||||
obrpc::UInt64 tenant_id;
|
||||
const obrpc::ObCreateTenantArg& create_tenant_arg = stmt.get_create_tenant_arg();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObCreateTenantArg&>(create_tenant_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(check_sys_var_options(ctx,
|
||||
stmt.get_sys_var_nodes(),
|
||||
stmt.get_create_tenant_arg().tenant_schema_,
|
||||
stmt.get_create_tenant_arg().sys_var_list_))) {
|
||||
LOG_WARN("check_sys_var_options failed", K(ret));
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed");
|
||||
} else if (OB_ISNULL(srv_rpc_proxy = task_exec_ctx->get_srv_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get server rpc proxy failed");
|
||||
} else if (OB_FAIL(common_rpc_proxy->create_tenant(create_tenant_arg, tenant_id))) {
|
||||
LOG_WARN("rpc proxy create tenant failed", K(ret));
|
||||
} else if (!create_tenant_arg.if_not_exist_ && OB_INVALID_ID == tenant_id) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("if_not_exist not set and tenant_id invalid tenant_id", K(create_tenant_arg), K(tenant_id), K(ret));
|
||||
} else if (OB_INVALID_ID != tenant_id) {
|
||||
// In fact, create tenant is success when come here. But we need
|
||||
// notify relating servers to ensure this tenant is created
|
||||
// indeed. Thus, client may receive a error packet for this
|
||||
// request, but the tenant is created perfectly.
|
||||
ObMySQLProxy* proxy = ctx.get_sql_proxy();
|
||||
ObUnitInfoGetter ui_getter;
|
||||
typedef ObSEArray<ObUnitInfoGetter::ObServerConfig, 10> ServerUnits;
|
||||
ServerUnits units;
|
||||
if (OB_ISNULL(proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("proxy is null");
|
||||
} else if (OB_FAIL(ui_getter.init(*proxy, &GCONF))) {
|
||||
LOG_WARN("init unit getter fail", K(ret));
|
||||
} else if (OB_FAIL(ui_getter.get_tenant_server_configs(tenant_id, units))) {
|
||||
LOG_WARN("get tenant server configs fail", K(ret));
|
||||
} else {
|
||||
int rret = ret;
|
||||
for (ServerUnits::iterator it = units.begin(); it != units.end(); ++it) {
|
||||
if (OB_FAIL(srv_rpc_proxy->to(it->server_).add_tenant_tmp(tenant_id))) {
|
||||
LOG_WARN("add tenant temp fail", K(ret));
|
||||
}
|
||||
// If it fails here, it does not mean that the create tenant process has failed.
|
||||
// Later, the server will obtain tenant information from rs according to the normal
|
||||
// process and timed tasks.
|
||||
if (!OB_SUCC(ret) && OB_SUCCESS == rret) {
|
||||
rret = ret;
|
||||
}
|
||||
}
|
||||
ret = rret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int check_sys_var_options(ObExecContext& ctx, const common::ObIArray<ObVariableSetStmt::VariableSetNode>& sys_var_nodes,
|
||||
share::schema::ObTenantSchema& tenant_schema, common::ObIArray<obrpc::ObSysVarIdValue>& sys_var_list)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
ObMySQLProxy* sql_proxy = NULL;
|
||||
ObPhysicalPlanCtx* plan_ctx = NULL;
|
||||
if (OB_ISNULL(session = ctx.get_my_session()) || OB_ISNULL(sql_proxy = ctx.get_sql_proxy()) ||
|
||||
OB_ISNULL(plan_ctx = ctx.get_physical_plan_ctx())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session or sql proxy or plan_ctx is NULL", K(session), K(sql_proxy), K(plan_ctx), K(ret));
|
||||
} else {
|
||||
// construct expr_ctx
|
||||
ObPhysicalPlan phy_plan;
|
||||
ObPhysicalPlanCtx phy_plan_ctx(ctx.get_allocator());
|
||||
SMART_VAR(ObExecContext, exec_ctx)
|
||||
{
|
||||
ObArenaAllocator allocator(
|
||||
common::ObModIds::OB_SQL_EXPR_CALC, OB_MALLOC_NORMAL_BLOCK_SIZE, session->get_effective_tenant_id());
|
||||
ObExprCtx expr_ctx;
|
||||
expr_ctx.phy_plan_ctx_ = &phy_plan_ctx;
|
||||
expr_ctx.my_session_ = session;
|
||||
expr_ctx.exec_ctx_ = &exec_ctx;
|
||||
expr_ctx.calc_buf_ = &allocator;
|
||||
expr_ctx.exec_ctx_->set_sql_proxy(sql_proxy);
|
||||
phy_plan_ctx.set_phy_plan(&phy_plan);
|
||||
const int64_t cur_time =
|
||||
plan_ctx->has_cur_time() ? plan_ctx->get_cur_time().get_timestamp() : ObTimeUtility::current_time();
|
||||
phy_plan_ctx.set_cur_time(cur_time, *session);
|
||||
|
||||
ObVariableSetStmt::VariableSetNode tmp_node; // just for init node
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < sys_var_nodes.count(); ++i) {
|
||||
ObVariableSetStmt::VariableSetNode& cur_node = tmp_node;
|
||||
ObBasicSysVar* sys_var = NULL;
|
||||
if (OB_FAIL(sys_var_nodes.at(i, cur_node))) {
|
||||
LOG_WARN("failed to access node from array", K(ret));
|
||||
} else if (!cur_node.is_system_variable_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("create tenant can only set system variables", K(cur_node), K(ret));
|
||||
} else if (OB_FAIL(session->get_sys_variable_by_name(cur_node.variable_name_, sys_var))) {
|
||||
LOG_WARN("fail to get_sys_variable_by_name", K(ret));
|
||||
} else if (OB_ISNULL(sys_var)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("got sys var is NULL", K(ret));
|
||||
} else if (cur_node.is_set_default_) { // set default, then do nothing
|
||||
} else {
|
||||
ObObj value_obj;
|
||||
// first:calculate value of expression
|
||||
ObNewRow tmp_row;
|
||||
RowDesc row_desc;
|
||||
ObExprGeneratorImpl expr_gen(0, 0, NULL, row_desc);
|
||||
ObSqlExpression sql_expr(ctx.get_allocator(), 0);
|
||||
if (OB_ISNULL(cur_node.value_expr_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("node.value_expr_ is NULL", K(ret));
|
||||
} else {
|
||||
if (!is_strict_mode(session->get_sql_mode())) {
|
||||
expr_ctx.cast_mode_ = CM_WARN_ON_FAIL;
|
||||
}
|
||||
if (OB_FAIL(expr_gen.generate(*cur_node.value_expr_, sql_expr))) {
|
||||
LOG_WARN("fail to fill sql expression", K(ret));
|
||||
} else if (FALSE_IT(phy_plan.set_regexp_op_count(expr_gen.get_cur_regexp_op_count()))) {
|
||||
} else if (FALSE_IT(phy_plan.set_like_op_count(expr_gen.get_cur_like_op_count()))) {
|
||||
} else if (OB_FAIL(sql_expr.calc(expr_ctx, tmp_row, value_obj))) {
|
||||
LOG_WARN("fail to calc value", K(*cur_node.value_expr_), K(ret));
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
}
|
||||
// second:convert value to dest type
|
||||
uint64_t fake_tenant_id = OB_INVALID_ID;
|
||||
ObSetVar set_var(cur_node.variable_name_,
|
||||
cur_node.set_scope_,
|
||||
cur_node.is_set_default_,
|
||||
fake_tenant_id,
|
||||
*expr_ctx.calc_buf_,
|
||||
*sql_proxy);
|
||||
if (OB_SUCC(ret)) {
|
||||
ObObj out_obj;
|
||||
const bool is_set_stmt = false;
|
||||
if (OB_FAIL(ObVariableSetExecutor::check_and_convert_sys_var(
|
||||
ctx, set_var, *sys_var, value_obj, out_obj, is_set_stmt))) {
|
||||
LOG_WARN("fail to check_and_convert_sys_var", K(cur_node), K(*sys_var), K(value_obj), K(ret));
|
||||
} else if (FALSE_IT(value_obj = out_obj)) {
|
||||
} else if (OB_FAIL(ObVariableSetExecutor::cast_value(
|
||||
ctx, cur_node, fake_tenant_id, *expr_ctx.calc_buf_, *sys_var, value_obj, out_obj))) {
|
||||
LOG_WARN("fail to cast value", K(cur_node), K(*sys_var), K(value_obj), K(ret));
|
||||
} else if (FALSE_IT(value_obj = out_obj)) {
|
||||
} else { /*do nothing*/
|
||||
}
|
||||
}
|
||||
// add variable value into ObCreateTenantArg
|
||||
if (OB_SUCC(ret)) {
|
||||
if (set_var.var_name_ == OB_SV_COLLATION_SERVER || set_var.var_name_ == OB_SV_COLLATION_DATABASE ||
|
||||
set_var.var_name_ == OB_SV_COLLATION_CONNECTION || set_var.var_name_ == OB_SV_CHARACTER_SET_SERVER ||
|
||||
set_var.var_name_ == OB_SV_CHARACTER_SET_DATABASE ||
|
||||
set_var.var_name_ == OB_SV_CHARACTER_SET_CONNECTION) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("collation or charset can not be modify temporarily", K(set_var), K(ret));
|
||||
} else {
|
||||
// read only should also modify tenant_schema
|
||||
if (set_var.var_name_ == OB_SV_READ_ONLY) {
|
||||
if (session->get_in_transaction()) {
|
||||
ret = OB_ERR_LOCK_OR_ACTIVE_TRANSACTION;
|
||||
|
||||
LOG_WARN("Can't execute the given command because "
|
||||
"you have active locked tables or an active transaction",
|
||||
K(ret));
|
||||
} else {
|
||||
tenant_schema.set_read_only(value_obj.get_bool());
|
||||
}
|
||||
}
|
||||
ObSysVarClassType sys_id = sys_var->get_type();
|
||||
ObString val_str;
|
||||
expr_ctx.calc_buf_ = &ctx.get_allocator(); // make sure use this allocator to keep ObString is valid
|
||||
EXPR_DEFINE_CAST_CTX(expr_ctx, CM_NONE);
|
||||
EXPR_GET_VARCHAR_V2(value_obj, val_str);
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_UNLIKELY(val_str.length() > OB_MAX_SYS_VAR_VAL_LENGTH)) {
|
||||
ret = OB_SIZE_OVERFLOW;
|
||||
LOG_WARN("set sysvar value is overflow",
|
||||
"max length",
|
||||
OB_MAX_SYS_VAR_VAL_LENGTH,
|
||||
"value length",
|
||||
val_str.length(),
|
||||
K(sys_id),
|
||||
K(val_str));
|
||||
} else if (OB_FAIL(sys_var_list.push_back(obrpc::ObSysVarIdValue(sys_id, val_str)))) {
|
||||
LOG_WARN("failed to push back", K(sys_id), K(val_str), K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end of for
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLockTenantExecutor::execute(ObExecContext& ctx, ObLockTenantStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObLockTenantArg& lock_tenant_arg = stmt.get_lock_tenant_arg();
|
||||
|
||||
if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed");
|
||||
} else if (OB_FAIL(common_rpc_proxy->lock_tenant(lock_tenant_arg))) {
|
||||
LOG_WARN("rpc proxy lock tenant failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int modify_progressive_merge_num_for_tenant(
|
||||
ObExecContext& ctx, const int64_t tenant_id, const int64_t progressive_merge_num)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObMySQLProxy* sql_proxy = ctx.get_sql_proxy();
|
||||
ObSchemaGetterGuard schema_guard;
|
||||
common::ObCommonSqlProxy* user_sql_proxy;
|
||||
common::ObOracleSqlProxy oracle_sql_proxy;
|
||||
if (OB_SYS_TENANT_ID == tenant_id && !GCONF.enable_sys_table_ddl) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "sys_table_ddl option");
|
||||
LOG_WARN("sys_table_ddl option should be enabled", K(ret));
|
||||
} else if (OB_INVALID_ID == tenant_id) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arguments", K(ret), K(tenant_id));
|
||||
} else if (nullptr == sql_proxy) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("error unexpected, sql proxy must not be null", K(ret));
|
||||
} else if (OB_FAIL(ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard(tenant_id, schema_guard))) {
|
||||
LOG_WARN("failed to get schema guard", K(ret));
|
||||
} else {
|
||||
observer::ObInnerSQLConnectionPool* pool = static_cast<observer::ObInnerSQLConnectionPool*>(sql_proxy->get_pool());
|
||||
if (OB_ISNULL(pool)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("error unexpected, pool must not be null", K(ret));
|
||||
} else if (OB_FAIL(oracle_sql_proxy.init(pool))) {
|
||||
LOG_WARN("fail to init oracle sql proxy", K(ret));
|
||||
} else {
|
||||
ObArray<const ObDatabaseSchema*> dbs;
|
||||
if (OB_FAIL(schema_guard.get_database_schemas_in_tenant(tenant_id, dbs))) {
|
||||
LOG_WARN("fail to get db schemas", K(ret), K(tenant_id));
|
||||
} else {
|
||||
for (int64_t i = 0; i < dbs.count() && OB_SUCC(ret); i++) {
|
||||
const ObDatabaseSchema* db = dbs.at(i);
|
||||
const uint64_t database_id = db->get_database_id();
|
||||
ObArray<const ObTableSchema*> tables;
|
||||
if (OB_FAIL(schema_guard.get_table_schemas_in_database(tenant_id, database_id, tables))) {
|
||||
LOG_WARN("fail to get table schemas", K(ret), K(tenant_id), K(database_id));
|
||||
}
|
||||
for (int64_t j = 0; j < tables.count() && OB_SUCC(ret); j++) {
|
||||
if (OB_FAIL(ctx.check_status())) {
|
||||
LOG_WARN("should stopped", K(ret));
|
||||
} else {
|
||||
const ObTableSchema* table = tables.at(j);
|
||||
bool do_alter = true;
|
||||
if (!table->has_partition()) {
|
||||
do_alter = false;
|
||||
}
|
||||
if (table->is_index_table()) {
|
||||
do_alter = false;
|
||||
}
|
||||
if (table->is_in_recyclebin()) {
|
||||
do_alter = false;
|
||||
}
|
||||
if (table->is_tmp_table()) {
|
||||
do_alter = false;
|
||||
}
|
||||
if (extract_pure_id(table->get_table_id()) == OB_ALL_CORE_TABLE_TID) {
|
||||
do_alter = false;
|
||||
}
|
||||
if (table->get_progressive_merge_num() == progressive_merge_num) {
|
||||
do_alter = false;
|
||||
}
|
||||
if (OB_SYS_TENANT_ID != tenant_id && table->is_sys_table()) {
|
||||
do_alter = false;
|
||||
}
|
||||
if (table->is_tmp_table()) {
|
||||
do_alter = false;
|
||||
}
|
||||
if (do_alter) {
|
||||
ObSqlString sql;
|
||||
int64_t affected_rows = 0;
|
||||
ObWorker::CompatMode mode;
|
||||
if (OB_FAIL(ObCompatModeGetter::get_tenant_mode(tenant_id, mode))) {
|
||||
LOG_WARN("fail to get tenant mode", K(ret), K(tenant_id));
|
||||
} else if (ObWorker::CompatMode::MYSQL == mode) {
|
||||
if (OB_FAIL(sql.assign_fmt("ALTER TABLE `%.*s`.`%.*s` SET PROGRESSIVE_MERGE_NUM = %ld",
|
||||
db->get_database_name_str().length(),
|
||||
db->get_database_name_str().ptr(),
|
||||
table->get_table_name_str().length(),
|
||||
table->get_table_name_str().ptr(),
|
||||
progressive_merge_num))) {
|
||||
LOG_WARN("sql assign_fmt failed", K(ret));
|
||||
} else {
|
||||
user_sql_proxy = sql_proxy;
|
||||
}
|
||||
} else if (ObWorker::CompatMode::ORACLE == mode) {
|
||||
if (OB_FAIL(sql.assign_fmt("ALTER TABLE \"%.*s\".\"%.*s\" SET PROGRESSIVE_MERGE_NUM = %ld",
|
||||
db->get_database_name_str().length(),
|
||||
db->get_database_name_str().ptr(),
|
||||
table->get_table_name_str().length(),
|
||||
table->get_table_name_str().ptr(),
|
||||
progressive_merge_num))) {
|
||||
LOG_WARN("sql assign_fmt failed", K(ret));
|
||||
} else {
|
||||
user_sql_proxy = &oracle_sql_proxy;
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("error unexpected, invalid tenant mode", K(ret), K(mode));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(user_sql_proxy->write(tenant_id, sql.ptr(), affected_rows))) {
|
||||
if (OB_ERR_OPERATION_ON_RECYCLE_OBJECT != ret) {
|
||||
LOG_WARN("execute sql failed", K(ret));
|
||||
} else {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // table loop end
|
||||
} // database loop end
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int modify_progressive_merge_num_for_all_tenants(ObExecContext& ctx, const int64_t progressive_merge_num)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSchemaGetterGuard schema_guard;
|
||||
ObSEArray<uint64_t, 32> tenant_ids;
|
||||
if (OB_FAIL(ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
|
||||
LOG_WARN("fail to get tenant schema guard", K(ret));
|
||||
} else if (OB_FAIL(schema_guard.get_tenant_ids(tenant_ids))) {
|
||||
LOG_WARN("fail to get tenant ids", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < tenant_ids.count(); ++i) {
|
||||
const int64_t tenant_id = tenant_ids.at(i);
|
||||
if (OB_FAIL(modify_progressive_merge_num_for_tenant(ctx, tenant_id, progressive_merge_num))) {
|
||||
LOG_WARN("fail to modify progressive merge num for tenant", K(ret), K(tenant_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObModifyTenantExecutor::execute(ObExecContext& ctx, ObModifyTenantStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObModifyTenantArg& modify_tenant_arg = stmt.get_modify_tenant_arg();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObModifyTenantArg&>(modify_tenant_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (-1 == stmt.get_progressive_merge_num()) {
|
||||
if (OB_FAIL(check_sys_var_options(ctx,
|
||||
stmt.get_sys_var_nodes(),
|
||||
stmt.get_modify_tenant_arg().tenant_schema_,
|
||||
stmt.get_modify_tenant_arg().sys_var_list_))) {
|
||||
LOG_WARN("check_sys_var_options failed", K(ret));
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed");
|
||||
} else if (OB_FAIL(common_rpc_proxy->modify_tenant(modify_tenant_arg))) {
|
||||
LOG_WARN("rpc proxy modify tenant failed", K(ret));
|
||||
}
|
||||
} else {
|
||||
if (modify_tenant_arg.tenant_schema_.get_tenant_name_str().case_compare("all") == 0) {
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
if (OB_ISNULL(session = ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session is NULL", K(ret));
|
||||
} else if (session->get_tenant_name().case_compare(ObString::make_string(OB_SYS_TENANT_NAME)) != 0) {
|
||||
ret = OB_ERR_NO_PRIVILEGE;
|
||||
LOG_WARN("no privilege", K(ret));
|
||||
} else if (OB_FAIL(modify_progressive_merge_num_for_all_tenants(ctx, stmt.get_progressive_merge_num()))) {
|
||||
LOG_WARN("modify_progressive_merge_num_for_tables failed", K(ret));
|
||||
}
|
||||
} else {
|
||||
ObSchemaGetterGuard schema_guard;
|
||||
const ObTenantSchema* tenant_schema = nullptr;
|
||||
if (OB_FAIL(
|
||||
ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) {
|
||||
LOG_WARN("fail to get tenant schema guard", K(ret));
|
||||
} else if (OB_FAIL(schema_guard.get_tenant_info(
|
||||
modify_tenant_arg.tenant_schema_.get_tenant_name_str(), tenant_schema))) {
|
||||
LOG_WARN("fail to get tenant info", K(ret));
|
||||
} else if (OB_ISNULL(tenant_schema)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("error unexpected, tenant schema must not be NULL", K(ret));
|
||||
} else if (OB_FAIL(modify_progressive_merge_num_for_tenant(
|
||||
ctx, tenant_schema->get_tenant_id(), stmt.get_progressive_merge_num()))) {
|
||||
LOG_WARN(
|
||||
"fail to modify progressive merge num for tenant", K(ret), "tenant_id", tenant_schema->get_tenant_id());
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDropTenantExecutor::execute(ObExecContext& ctx, ObDropTenantStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObDropTenantArg& drop_tenant_arg = stmt.get_drop_tenant_arg();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObDropTenantArg&>(drop_tenant_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed");
|
||||
} else if (OB_FAIL(common_rpc_proxy->drop_tenant(drop_tenant_arg))) {
|
||||
LOG_WARN("rpc proxy drop tenant failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPurgeTenantExecutor::execute(ObExecContext& ctx, ObPurgeTenantStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const obrpc::ObPurgeTenantArg& purge_tenant_arg = stmt.get_purge_tenant_arg();
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
SQL_ENG_LOG(WARN, "fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObPurgeTenantArg&>(purge_tenant_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "get task executor context failed");
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
SQL_ENG_LOG(WARN, "get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->purge_tenant(purge_tenant_arg))) {
|
||||
SQL_ENG_LOG(WARN, "rpc proxy purge tenant failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPurgeRecycleBinExecutor::execute(ObExecContext& ctx, ObPurgeRecycleBinStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
// use to test purge recyclebin objects
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObPurgeRecycleBinArg& purge_recyclebin_arg = stmt.get_purge_recyclebin_arg();
|
||||
|
||||
// int64_t current_time = ObTimeUtility::current_time();
|
||||
// obrpc::Int64 expire_time = current_time - GCONF.schema_history_expire_time;
|
||||
obrpc::Int64 affected_rows = 0;
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObPurgeRecycleBinArg&>(purge_recyclebin_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed");
|
||||
} else {
|
||||
bool is_tenant_finish = false;
|
||||
int64_t total_purge_count = 0;
|
||||
while (OB_SUCC(ret) && !is_tenant_finish) {
|
||||
int64_t start_time = ObTimeUtility::current_time();
|
||||
if (OB_FAIL(common_rpc_proxy->purge_expire_recycle_objects(purge_recyclebin_arg, affected_rows))) {
|
||||
LOG_WARN("purge reyclebin objects failed", K(ret), K(affected_rows), K(purge_recyclebin_arg));
|
||||
is_tenant_finish = false;
|
||||
} else {
|
||||
is_tenant_finish = obrpc::ObPurgeRecycleBinArg::DEFAULT_PURGE_EACH_TIME == affected_rows ? false : true;
|
||||
total_purge_count += affected_rows;
|
||||
}
|
||||
int64_t cost_time = ObTimeUtility::current_time() - start_time;
|
||||
LOG_INFO("purge recycle objects",
|
||||
K(ret),
|
||||
K(cost_time),
|
||||
K(total_purge_count),
|
||||
K(purge_recyclebin_arg),
|
||||
K(affected_rows),
|
||||
K(is_tenant_finish));
|
||||
}
|
||||
LOG_INFO("purge recyclebin success", K(purge_recyclebin_arg), K(total_purge_count), K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateRestorePointExecutor::execute(ObExecContext& ctx, ObCreateRestorePointStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const int64_t tenant_id = ctx.get_my_session()->get_effective_tenant_id();
|
||||
stmt.set_tenant_id(tenant_id);
|
||||
const obrpc::ObCreateRestorePointArg& create_restore_point_arg = stmt.get_create_restore_point_arg();
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed");
|
||||
} else if (OB_FAIL(common_rpc_proxy->create_restore_point(create_restore_point_arg))) {
|
||||
LOG_WARN("rpc proxy create restore point failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int ObDropRestorePointExecutor::execute(ObExecContext& ctx, ObDropRestorePointStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const int64_t tenant_id = ctx.get_my_session()->get_effective_tenant_id();
|
||||
stmt.set_tenant_id(tenant_id);
|
||||
|
||||
const obrpc::ObDropRestorePointArg& drop_restore_point_arg = stmt.get_drop_restore_point_arg();
|
||||
|
||||
if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed");
|
||||
} else if (OB_FAIL(common_rpc_proxy->drop_restore_point(drop_restore_point_arg))) {
|
||||
LOG_WARN("rpc proxy drop restore point failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
65
src/sql/engine/cmd/ob_tenant_executor.h
Normal file
65
src/sql/engine/cmd/ob_tenant_executor.h
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef __OB_SQL_TENANT_EXECUTOR_H__
|
||||
#define __OB_SQL_TENANT_EXECUTOR_H__
|
||||
#include "share/ob_define.h"
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
#define DEF_SIMPLE_EXECUTOR(name) \
|
||||
class name##Executor { \
|
||||
public: \
|
||||
name##Executor() \
|
||||
{} \
|
||||
virtual ~name##Executor() \
|
||||
{} \
|
||||
int execute(ObExecContext& ctx, name##Stmt& stmt); \
|
||||
\
|
||||
private: \
|
||||
DISALLOW_COPY_AND_ASSIGN(name##Executor); \
|
||||
}
|
||||
|
||||
class ObExecContext;
|
||||
class ObCreateTenantStmt;
|
||||
class ObDropTenantStmt;
|
||||
class ObLockTenantStmt;
|
||||
class ObModifyTenantStmt;
|
||||
class ObChangeTenantStmt;
|
||||
class ObFlashBackTenantStmt;
|
||||
class ObPurgeTenantStmt;
|
||||
class ObPurgeRecycleBinStmt;
|
||||
class ObCreateRestorePointStmt;
|
||||
class ObDropRestorePointStmt;
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObCreateTenant);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObDropTenant);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObModifyTenant);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObLockTenant);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObFlashBackTenant);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObPurgeTenant);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObPurgeRecycleBin);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObCreateRestorePoint);
|
||||
|
||||
DEF_SIMPLE_EXECUTOR(ObDropRestorePoint);
|
||||
|
||||
#undef DEF_SIMPLE_EXECUTOR
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif /* __OB_SQL_TENANT_EXECUTOR_H__ */
|
||||
//// end of header file
|
||||
83
src/sql/engine/cmd/ob_udf_executor.cpp
Normal file
83
src/sql/engine/cmd/ob_udf_executor.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/engine/cmd/ob_udf_executor.h"
|
||||
#include "lib/mysqlclient/ob_mysql_proxy.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "sql/resolver/ddl/ob_create_func_stmt.h"
|
||||
#include "sql/resolver/ddl/ob_drop_func_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/engine/ob_physical_plan.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/code_generator/ob_expr_generator_impl.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace share::schema;
|
||||
namespace sql {
|
||||
|
||||
int ObCreateFuncExecutor::execute(ObExecContext& ctx, ObCreateFuncStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObCreateUserDefinedFunctionArg& create_udf_arg = stmt.get_create_func_arg();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObCreateUserDefinedFunctionArg&>(create_udf_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed", K(ret));
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->create_udf(create_udf_arg))) {
|
||||
LOG_WARN("rpc proxy create udf failed", K(ret), "dst", common_rpc_proxy->get_server());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDropFuncExecutor::execute(ObExecContext& ctx, ObDropFuncStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const obrpc::ObDropUserDefinedFunctionArg& drop_func_arg = stmt.get_drop_func_arg();
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
const_cast<obrpc::ObDropUserDefinedFunctionArg&>(drop_func_arg).ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed", K(ret));
|
||||
} else if (OB_FAIL(task_exec_ctx->get_common_rpc(common_rpc_proxy))) {
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("common rpc proxy should not be null", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->drop_udf(drop_func_arg))) {
|
||||
LOG_WARN("rpc proxy create udf failed", K(ret), "dst", common_rpc_proxy->get_server());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
58
src/sql/engine/cmd/ob_udf_executor.h
Normal file
58
src/sql/engine/cmd/ob_udf_executor.h
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OB_UDF_EXECUTOR_H_
|
||||
#define OB_UDF_EXECUTOR_H_
|
||||
|
||||
#include "common/object/ob_object.h"
|
||||
#include "lib/container/ob_se_array.h"
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
class ObIAllocator;
|
||||
class ObExprCtx;
|
||||
namespace sqlclient {
|
||||
class ObMySQLProxy;
|
||||
}
|
||||
} // namespace common
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObRawExpr;
|
||||
class ObCreateFuncStmt;
|
||||
class ObCreateFuncExecutor {
|
||||
public:
|
||||
const static int OB_DEFAULT_ARRAY_SIZE = 16;
|
||||
ObCreateFuncExecutor()
|
||||
{}
|
||||
virtual ~ObCreateFuncExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObCreateFuncStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObCreateFuncExecutor);
|
||||
};
|
||||
|
||||
class ObDropFuncStmt;
|
||||
class ObDropFuncExecutor {
|
||||
public:
|
||||
ObDropFuncExecutor()
|
||||
{}
|
||||
virtual ~ObDropFuncExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObDropFuncStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObDropFuncExecutor);
|
||||
};
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
||||
#endif
|
||||
670
src/sql/engine/cmd/ob_user_cmd_executor.cpp
Normal file
670
src/sql/engine/cmd/ob_user_cmd_executor.cpp
Normal file
@ -0,0 +1,670 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/engine/cmd/ob_user_cmd_executor.h"
|
||||
|
||||
#include "lib/encrypt/ob_encrypted_helper.h"
|
||||
#include "lib/string/ob_sql_string.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "sql/resolver/dcl/ob_create_user_stmt.h"
|
||||
#include "sql/resolver/dcl/ob_drop_user_stmt.h"
|
||||
#include "sql/resolver/dcl/ob_lock_user_stmt.h"
|
||||
#include "sql/resolver/dcl/ob_rename_user_stmt.h"
|
||||
#include "sql/resolver/dcl/ob_alter_user_profile_stmt.h"
|
||||
#include "sql/resolver/dcl/ob_alter_user_primary_zone_stmt.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace obrpc;
|
||||
using namespace share::schema;
|
||||
namespace sql {
|
||||
int ObCreateUserExecutor::encrypt_passwd(
|
||||
const common::ObString& pwd, common::ObString& encrypted_pwd, char* enc_buf, int64_t buf_len)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(enc_buf)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("enc_buf is NULL", K(ret));
|
||||
} else if (buf_len < SCRAMBLE_LENGTH * 2 + 1) {
|
||||
ret = OB_BUF_NOT_ENOUGH;
|
||||
LOG_WARN("Encrypt buf not enough");
|
||||
} else {
|
||||
encrypted_pwd.assign_ptr(enc_buf, SCRAMBLE_LENGTH * 2 + 1);
|
||||
if (OB_FAIL(ObEncryptedHelper::encrypt_passwd_to_stage2(pwd, encrypted_pwd))) {
|
||||
SQL_ENG_LOG(WARN, "failed to encrypt passwd", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateUserExecutor::userinfo_extract_user_name(const common::ObIArray<share::schema::ObUserInfo>& user_infos,
|
||||
const common::ObIArray<int64_t>& index, common::ObIArray<common::ObString>& users,
|
||||
common::ObIArray<common::ObString>& hosts)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
users.reset();
|
||||
hosts.reset();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < index.count(); ++i) {
|
||||
int64_t in = index.at(i);
|
||||
if (OB_UNLIKELY(in < 0) || OB_UNLIKELY(in >= user_infos.count())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("Userinfo index out of range", K(user_infos), K(index), K(in));
|
||||
} else if (OB_FAIL(users.push_back(user_infos.at(in).get_user_name_str()))) {
|
||||
LOG_WARN("Failed to add username", K(user_infos), K(index));
|
||||
} else if (OB_FAIL(hosts.push_back(user_infos.at(in).get_host_name_str()))) {
|
||||
LOG_WARN("Failed to add username", K(user_infos), K(index));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateUserExecutor::execute(ObExecContext& ctx, ObCreateUserStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const uint64_t tenant_id = stmt.get_tenant_id();
|
||||
const ObStrings& users = stmt.get_users();
|
||||
const bool if_not_exist = stmt.get_if_not_exists();
|
||||
const int64_t FIX_MEMBER_CNT = 4;
|
||||
if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed");
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed");
|
||||
} else if (OB_UNLIKELY(users.count() <= FIX_MEMBER_CNT) || OB_UNLIKELY(0 != users.count() % FIX_MEMBER_CNT)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("Resolve create user error. Users should have user and pwd", "ObStrings count", users.count());
|
||||
} else {
|
||||
ObString user_name;
|
||||
ObString host_name;
|
||||
ObString pwd;
|
||||
ObString need_enc;
|
||||
ObString ssl_type;
|
||||
ObString ssl_cipher;
|
||||
ObString x509_issuer;
|
||||
ObString x509_subject;
|
||||
ObSSLType ssl_type_enum = ObSSLType::SSL_TYPE_NOT_SPECIFIED;
|
||||
ObCreateUserArg& arg = static_cast<ObCreateUserArg&>(stmt.get_ddl_arg());
|
||||
arg.tenant_id_ = tenant_id;
|
||||
arg.user_infos_.reset();
|
||||
arg.if_not_exist_ = if_not_exist;
|
||||
const int64_t users_cnt = users.count() - FIX_MEMBER_CNT;
|
||||
|
||||
if (OB_FAIL(users.get_string(users_cnt, ssl_type))) {
|
||||
LOG_WARN("Get string from ObStrings error", K(ret));
|
||||
} else if (OB_FAIL(users.get_string(users_cnt + 1, ssl_cipher))) {
|
||||
LOG_WARN("Get string from ObStrings error", K(ret));
|
||||
} else if (OB_FAIL(users.get_string(users_cnt + 2, x509_issuer))) {
|
||||
LOG_WARN("Get string from ObStrings error", K(ret));
|
||||
} else if (OB_FAIL(users.get_string(users_cnt + 3, x509_subject))) {
|
||||
LOG_WARN("Get string from ObStrings error", K(ret));
|
||||
} else if (OB_UNLIKELY(ObSSLType::SSL_TYPE_MAX == (ssl_type_enum = get_ssl_type_from_string(ssl_type)))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("known ssl_type", K(ssl_type), K(ret));
|
||||
}
|
||||
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < users_cnt; i += FIX_MEMBER_CNT) {
|
||||
if (OB_FAIL(users.get_string(i, user_name))) {
|
||||
LOG_WARN("Get string from ObStrings error", "count", users.count(), K(i), K(ret));
|
||||
} else if (OB_FAIL(users.get_string(i + 1, host_name))) {
|
||||
LOG_WARN("Get string from ObStrings error", "count", users.count(), K(i), K(ret));
|
||||
} else if (OB_FAIL(users.get_string(i + 2, pwd))) {
|
||||
LOG_WARN("Get string from ObStrings error", "count", users.count(), K(i), K(ret));
|
||||
} else if (OB_FAIL(users.get_string(i + 3, need_enc))) {
|
||||
LOG_WARN("Get string from ObStrings error", "count", users.count(), K(i), K(ret));
|
||||
} else {
|
||||
ObUserInfo user_info;
|
||||
if (ObString::make_string("YES") == need_enc) {
|
||||
if (pwd.length() > 0) {
|
||||
ObString pwd_enc;
|
||||
char enc_buf[ENC_BUF_LEN] = {0};
|
||||
if (OB_FAIL(encrypt_passwd(pwd, pwd_enc, enc_buf, ENC_BUF_LEN))) {
|
||||
LOG_WARN("Encrypt password failed", K(ret));
|
||||
} else if (OB_FAIL(user_info.set_passwd(pwd_enc))) {
|
||||
LOG_WARN("set password failed", K(ret));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(user_info.set_passwd(pwd))) {
|
||||
LOG_WARN("Failed to set password", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(user_info.set_user_name(user_name))) {
|
||||
LOG_WARN("set user name failed", K(ret));
|
||||
} else if (OB_FAIL(user_info.set_host(host_name))) {
|
||||
LOG_WARN("set host name failed", K(ret));
|
||||
} else if (FALSE_IT(user_info.set_ssl_type(ssl_type_enum))) {
|
||||
LOG_WARN("set ssl_type failed", K(ret));
|
||||
} else if (OB_FAIL(user_info.set_ssl_cipher(ssl_cipher))) {
|
||||
LOG_WARN("set ssl_cipher failed", K(ret));
|
||||
} else if (OB_FAIL(user_info.set_x509_issuer(x509_issuer))) {
|
||||
LOG_WARN("set x509_issuer failed", K(ret));
|
||||
} else if (OB_FAIL(user_info.set_x509_subject(x509_subject))) {
|
||||
LOG_WARN("set x509_subject failed", K(ret));
|
||||
} else if (FALSE_IT(user_info.set_password_last_changed(ObTimeUtility::current_time()))) {
|
||||
LOG_WARN("set set_password_last_changed failed", K(ret));
|
||||
} else {
|
||||
user_info.set_tenant_id(tenant_id);
|
||||
if (user_name.empty()) {
|
||||
user_info.set_user_id(combine_id(tenant_id, OB_EMPTY_USER_ID));
|
||||
}
|
||||
user_info.set_profile_id(stmt.get_profile_id());
|
||||
if (OB_FAIL(arg.user_infos_.push_back(user_info))) {
|
||||
LOG_WARN("Add user info to array error", K(ret));
|
||||
} else {
|
||||
LOG_DEBUG("Add user info to array", K(user_info));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(create_user(common_rpc_proxy, arg))) {
|
||||
LOG_WARN("Create user rpc failed", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObCreateUserExecutor::create_user(obrpc::ObCommonRpcProxy* rpc_proxy, const obrpc::ObCreateUserArg& arg) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSArray<int64_t> failed_index;
|
||||
ObSqlString fail_msg;
|
||||
if (OB_ISNULL(rpc_proxy)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("Input argument error", K(rpc_proxy), K(ret));
|
||||
} else if (OB_FAIL(rpc_proxy->create_user(arg, failed_index))) {
|
||||
LOG_WARN("Create user error", K(ret));
|
||||
} else if (0 != failed_index.count()) {
|
||||
ObSArray<ObString> failed_users;
|
||||
ObSArray<ObString> failed_hosts;
|
||||
if (OB_FAIL(userinfo_extract_user_name(arg.user_infos_, failed_index, failed_users, failed_hosts))) {
|
||||
LOG_WARN("Failed to extract user name", K(arg.user_infos_), K(failed_index), K(ret));
|
||||
} else if (OB_FAIL(ObDropUserExecutor::build_fail_msg(failed_users, failed_hosts, fail_msg))) {
|
||||
LOG_WARN("Build fail msg error", K(ret));
|
||||
} else {
|
||||
ret = OB_CANNOT_USER;
|
||||
LOG_USER_ERROR(OB_CANNOT_USER, (int)strlen("CREATE USER"), "CREATE USER", (int)fail_msg.length(), fail_msg.ptr());
|
||||
}
|
||||
} else {
|
||||
// Create user completely success
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDropUserExecutor::build_fail_msg(const common::ObIArray<common::ObString>& users,
|
||||
const common::ObIArray<common::ObString>& hosts, common::ObSqlString& msg)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(users.count() < 1) || OB_UNLIKELY(users.count() != hosts.count())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(users.count()), K(hosts.count()), K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < users.count(); ++i) {
|
||||
if (0 != i && OB_FAIL(msg.append_fmt(","))) {
|
||||
LOG_WARN("Build msg fail", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
const ObString& user = users.at(i);
|
||||
const ObString& host = hosts.at(i);
|
||||
if (OB_UNLIKELY(user.empty()) || OB_UNLIKELY(host.empty())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("Username is invalid", K(ret), K(user), K(host));
|
||||
} else {
|
||||
if (OB_FAIL(msg.append_fmt("'%.*s'@'%.*s'", user.length(), user.ptr(), host.length(), host.ptr()))) {
|
||||
LOG_WARN("Build msg fail", K(user), K(host), K(ret));
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDropUserExecutor::string_array_index_extract(const common::ObIArray<common::ObString>& src_users,
|
||||
const common::ObIArray<common::ObString>& src_hosts, const common::ObIArray<int64_t>& index,
|
||||
common::ObIArray<common::ObString>& dst_users, common::ObIArray<common::ObString>& dst_hosts)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
dst_users.reset();
|
||||
dst_hosts.reset();
|
||||
int64_t in = 0;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < index.count(); ++i) {
|
||||
in = index.at(i);
|
||||
if (in >= src_users.count() || in < 0) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("String index out of range", K(ret), K(in), K(src_users.count()));
|
||||
} else if (OB_FAIL(dst_users.push_back(src_users.at(in)))) {
|
||||
LOG_WARN("Failed to push back user", K(ret));
|
||||
} else if (OB_FAIL(dst_hosts.push_back(src_hosts.at(in)))) {
|
||||
LOG_WARN("Failed to push back host", K(ret));
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDropUserExecutor::execute(ObExecContext& ctx, ObDropUserStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const uint64_t tenant_id = stmt.get_tenant_id();
|
||||
const ObStrings* user_names = NULL;
|
||||
if (OB_INVALID_ID == tenant_id) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("tenant is invalid", K(ret));
|
||||
} else if (OB_ISNULL(user_names = stmt.get_users())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("names is NULL", K(ret));
|
||||
} else if (OB_UNLIKELY(user_names->count() % 2 != 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("user not specified", K(ret));
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed", K(ret));
|
||||
} else if (NULL == (common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else {
|
||||
ObString user_name;
|
||||
ObString host_name;
|
||||
ObDropUserArg& arg = static_cast<ObDropUserArg&>(stmt.get_ddl_arg());
|
||||
arg.tenant_id_ = tenant_id;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < user_names->count(); i += 2) {
|
||||
if (OB_FAIL(user_names->get_string(i, user_name))) {
|
||||
LOG_WARN("Get user name failed", K(ret));
|
||||
} else if (OB_FAIL(user_names->get_string(i + 1, host_name))) {
|
||||
LOG_WARN("Get host name failed", K(ret));
|
||||
} else if (OB_FAIL(arg.users_.push_back(user_name))) {
|
||||
LOG_WARN("Add user name failed", K(ret));
|
||||
} else if (OB_FAIL(arg.hosts_.push_back(host_name))) {
|
||||
LOG_WARN("Add host name failed", K(ret));
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(drop_user(common_rpc_proxy, arg))) {
|
||||
LOG_WARN("Drop user completely failed", K(ret));
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDropUserExecutor::drop_user(obrpc::ObCommonRpcProxy* rpc_proxy, const obrpc::ObDropUserArg& arg)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!arg.is_valid())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("arg is invalid", K(arg), K(ret));
|
||||
} else if (OB_UNLIKELY(arg.users_.count() < 1)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("user not specified", K(ret));
|
||||
} else if (OB_ISNULL(rpc_proxy)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("rpc_proxy is null", K(ret));
|
||||
} else {
|
||||
ObSArray<int64_t> failed_index;
|
||||
ObSqlString fail_msg;
|
||||
if (OB_FAIL(rpc_proxy->drop_user(arg, failed_index))) {
|
||||
LOG_WARN("Lock user failed", K(ret));
|
||||
if (OB_FAIL(ObDropUserExecutor::build_fail_msg(arg.users_, arg.hosts_, fail_msg))) {
|
||||
LOG_WARN("Build fail msg error", K(arg), K(ret));
|
||||
} else {
|
||||
ret = OB_CANNOT_USER;
|
||||
LOG_USER_ERROR(OB_CANNOT_USER, (int)strlen("DROP USER"), "DROP USER", (int)fail_msg.length(), fail_msg.ptr());
|
||||
}
|
||||
} else if (0 != failed_index.count()) {
|
||||
ObSArray<ObString> failed_users;
|
||||
ObSArray<ObString> failed_hosts;
|
||||
if (OB_FAIL(ObDropUserExecutor::string_array_index_extract(
|
||||
arg.users_, arg.hosts_, failed_index, failed_users, failed_hosts))) {
|
||||
LOG_WARN("Failed to extract user name", K(arg), K(ret));
|
||||
} else if (OB_FAIL(ObDropUserExecutor::build_fail_msg(failed_users, failed_hosts, fail_msg))) {
|
||||
LOG_WARN("Build fail msg error", K(arg), K(ret));
|
||||
} else {
|
||||
ret = OB_CANNOT_USER;
|
||||
LOG_USER_ERROR(OB_CANNOT_USER, (int)strlen("DROP USER"), "DROP USER", (int)fail_msg.length(), fail_msg.ptr());
|
||||
}
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLockUserExecutor::execute(ObExecContext& ctx, ObLockUserStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const uint64_t tenant_id = stmt.get_tenant_id();
|
||||
const ObStrings* user_names = NULL;
|
||||
if (OB_UNLIKELY(OB_INVALID_ID == tenant_id)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("tenant is invalid", K(ret));
|
||||
} else if (OB_ISNULL(user_names = stmt.get_users())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("names is NULL", K(ret));
|
||||
} else if (OB_UNLIKELY(user_names->count() % 2 != 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("user not specified", K(ret));
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else {
|
||||
ObString user_name;
|
||||
ObString host_name;
|
||||
ObLockUserArg& arg = static_cast<ObLockUserArg&>(stmt.get_ddl_arg());
|
||||
arg.tenant_id_ = tenant_id;
|
||||
arg.locked_ = stmt.is_locked();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < user_names->count(); i += 2) {
|
||||
if (OB_FAIL(user_names->get_string(i, user_name))) {
|
||||
LOG_WARN("Get user name failed", K(ret));
|
||||
} else if (OB_FAIL(user_names->get_string(i + 1, host_name))) {
|
||||
LOG_WARN("Get host name failed", K(ret));
|
||||
} else if (OB_FAIL(arg.users_.push_back(user_name))) {
|
||||
LOG_WARN("Add user name failed", K(ret));
|
||||
} else if (OB_FAIL(arg.hosts_.push_back(host_name))) {
|
||||
LOG_WARN("Add host name failed", K(ret));
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(lock_user(common_rpc_proxy, arg))) {
|
||||
LOG_WARN("Rename user completely failed", K(arg), K(ret));
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObLockUserExecutor::lock_user(obrpc::ObCommonRpcProxy* rpc_proxy, const obrpc::ObLockUserArg& arg)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!arg.is_valid())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("arg is invalid", K(arg), K(ret));
|
||||
} else if (OB_UNLIKELY(arg.users_.count() < 1)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("user not specified", K(ret));
|
||||
} else if (OB_ISNULL(rpc_proxy)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("rpc_proxy is null", K(ret));
|
||||
} else {
|
||||
ObSArray<int64_t> failed_index;
|
||||
ObSqlString fail_msg;
|
||||
if (OB_FAIL(rpc_proxy->lock_user(arg, failed_index))) {
|
||||
LOG_WARN("Lock user failed", K(ret));
|
||||
if (OB_FAIL(ObDropUserExecutor::build_fail_msg(arg.users_, arg.hosts_, fail_msg))) {
|
||||
LOG_WARN("Build fail msg error", K(arg), K(ret));
|
||||
} else {
|
||||
ret = OB_CANNOT_USER;
|
||||
LOG_USER_ERROR(OB_CANNOT_USER, (int)strlen("LOCK USER"), "LOCK USER", (int)fail_msg.length(), fail_msg.ptr());
|
||||
}
|
||||
} else if (0 != failed_index.count()) {
|
||||
ObSArray<ObString> failed_users;
|
||||
ObSArray<ObString> failed_hosts;
|
||||
if (OB_FAIL(ObDropUserExecutor::string_array_index_extract(
|
||||
arg.users_, arg.hosts_, failed_index, failed_users, failed_hosts))) {
|
||||
LOG_WARN("Failed to extract user name", K(arg), K(ret));
|
||||
} else {
|
||||
if (OB_FAIL(ObDropUserExecutor::build_fail_msg(failed_users, failed_hosts, fail_msg))) {
|
||||
LOG_WARN("Build fail msg error", K(arg), K(ret));
|
||||
} else {
|
||||
ret = OB_CANNOT_USER;
|
||||
LOG_USER_ERROR(OB_CANNOT_USER, (int)strlen("LOCK USER"), "LOCK USER", (int)fail_msg.length(), fail_msg.ptr());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObAlterUserProfileExecutor::set_role_exec(ObExecContext& ctx, ObAlterUserProfileStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
uint64_t role_id = OB_INVALID_ID;
|
||||
CK(1 == stmt.get_set_role_flag());
|
||||
if (OB_ISNULL(session = ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session is NULL", K(ret));
|
||||
} else {
|
||||
const uint64_t tenant_id = session->get_effective_tenant_id();
|
||||
int disable_flag = 0;
|
||||
const ObUserInfo* user_info = NULL;
|
||||
common::ObSEArray<uint64_t, 8>& enable_role_id_array = session->get_enable_role_array();
|
||||
ObSchemaGetterGuard schema_guard;
|
||||
|
||||
obrpc::ObAlterUserProfileArg& arg = static_cast<obrpc::ObAlterUserProfileArg&>(stmt.get_ddl_arg());
|
||||
OZ(GCTX.schema_service_->get_tenant_schema_guard(tenant_id, schema_guard));
|
||||
OZ(schema_guard.get_user_info(session->get_user_id(), user_info));
|
||||
if (OB_SUCC(ret) && NULL == user_info) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("user info is null", K(ret));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
switch (arg.default_role_flag_) {
|
||||
case OB_DEFAULT_ROLE_ALL:
|
||||
OZ(session->set_enable_role_array(user_info->get_role_id_array()));
|
||||
break;
|
||||
case OB_DEFAULT_ROLE_NONE:
|
||||
OX(enable_role_id_array.reset());
|
||||
break;
|
||||
case OB_DEFAULT_ROLE_LIST:
|
||||
OX(enable_role_id_array.reset());
|
||||
for (int i = 0; OB_SUCC(ret) && i < arg.role_id_array_.count(); i++) {
|
||||
OX(role_id = arg.role_id_array_.at(i));
|
||||
OZ(enable_role_id_array.push_back(role_id));
|
||||
}
|
||||
break;
|
||||
case OB_DEFAULT_ROLE_ALL_EXCEPT:
|
||||
int64_t idx;
|
||||
OX(enable_role_id_array.reset());
|
||||
/* scan all role granted to the user */
|
||||
for (int i = 0; OB_SUCC(ret) && i < user_info->get_role_id_array().count(); i++) {
|
||||
OX(role_id = user_info->get_role_id_array().at(i));
|
||||
/* if not in execpt set, then push back */
|
||||
if (OB_SUCC(ret) && !has_exist_in_array(arg.role_id_array_, role_id)) {
|
||||
OZ(enable_role_id_array.push_back(role_id));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
OZ(enable_role_id_array.push_back(combine_id(session->get_effective_tenant_id(), OB_ORA_PUBLIC_ROLE_ID)));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObAlterUserProfileExecutor::execute(ObExecContext& ctx, ObAlterUserProfileStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
|
||||
if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed", K(ret));
|
||||
} else if (1 == stmt.get_set_role_flag()) {
|
||||
OZ(set_role_exec(ctx, stmt));
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_FAIL(common_rpc_proxy->alter_user_profile(stmt.get_ddl_arg()))) {
|
||||
LOG_WARN("alter user profile failed", K(stmt.get_ddl_arg()), K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRenameUserExecutor::execute(ObExecContext& ctx, ObRenameUserStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
const uint64_t tenant_id = stmt.get_tenant_id();
|
||||
const ObStrings* rename_infos = NULL;
|
||||
if (OB_INVALID_ID == tenant_id) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("tenant is invalid", K(ret));
|
||||
} else if (OB_ISNULL(rename_infos = stmt.get_rename_infos())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("names is NULL", K(ret));
|
||||
} else if (rename_infos->count() < 1) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("user not specified", K(ret));
|
||||
} else if (rename_infos->count() % 4 != 0) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("old and new names count not match", K(ret));
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else {
|
||||
ObString old_username;
|
||||
ObString old_hostname;
|
||||
ObString new_username;
|
||||
ObString new_hostname;
|
||||
ObRenameUserArg& arg = static_cast<ObRenameUserArg&>(stmt.get_ddl_arg());
|
||||
arg.tenant_id_ = tenant_id;
|
||||
// rename_infos arr contains old names and new names in pairs, so step is 2
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < rename_infos->count(); i += 4) {
|
||||
if (OB_FAIL(rename_infos->get_string(i, old_username))) {
|
||||
LOG_WARN("Get origin name failed", K(ret));
|
||||
} else if (OB_FAIL(rename_infos->get_string(i + 1, old_hostname))) {
|
||||
LOG_WARN("Get to name failed", K(ret));
|
||||
} else if (OB_FAIL(rename_infos->get_string(i + 2, new_username))) {
|
||||
LOG_WARN("Get to name failed", K(ret));
|
||||
} else if (OB_FAIL(rename_infos->get_string(i + 3, new_hostname))) {
|
||||
LOG_WARN("Get to name failed", K(ret));
|
||||
} else if (OB_FAIL(arg.old_users_.push_back(old_username))) {
|
||||
LOG_WARN("Add origin user name failed", K(ret));
|
||||
} else if (OB_FAIL(arg.old_hosts_.push_back(old_hostname))) {
|
||||
LOG_WARN("Add origin host name failed", K(ret));
|
||||
} else if (OB_FAIL(arg.new_users_.push_back(new_username))) {
|
||||
LOG_WARN("Add new user name failed", K(ret));
|
||||
} else if (OB_FAIL(arg.new_hosts_.push_back(new_hostname))) {
|
||||
LOG_WARN("Add new host name failed", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(rename_user(common_rpc_proxy, arg))) {
|
||||
LOG_WARN("Rename user completely failed", K(arg), K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRenameUserExecutor::rename_user(obrpc::ObCommonRpcProxy* rpc_proxy, const obrpc::ObRenameUserArg& arg)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!arg.is_valid())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("Invalid arg", K(arg), K(ret));
|
||||
} else if (OB_UNLIKELY(arg.old_users_.count() < 1)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("user not specified", K(arg), K(ret));
|
||||
} else if (OB_ISNULL(rpc_proxy)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("rpc_proxy is null", K(ret));
|
||||
} else {
|
||||
ObSArray<int64_t> failed_index;
|
||||
ObSqlString fail_msg;
|
||||
if (OB_FAIL(rpc_proxy->rename_user(arg, failed_index))) {
|
||||
LOG_WARN("Rename user failed", K(ret));
|
||||
if (OB_FAIL(ObDropUserExecutor::build_fail_msg(arg.old_users_, arg.old_hosts_, fail_msg))) {
|
||||
LOG_WARN("Build fail msg error", K(arg), K(ret));
|
||||
} else {
|
||||
ret = OB_CANNOT_USER;
|
||||
LOG_USER_ERROR(
|
||||
OB_CANNOT_USER, (int)strlen("RENAME USER"), "RENAME USER", (int)fail_msg.length(), fail_msg.ptr());
|
||||
}
|
||||
} else if (0 != failed_index.count()) {
|
||||
ObSArray<ObString> failed_users;
|
||||
ObSArray<ObString> failed_hosts;
|
||||
if (OB_FAIL(ObDropUserExecutor::string_array_index_extract(
|
||||
arg.old_users_, arg.old_hosts_, failed_index, failed_users, failed_hosts))) {
|
||||
LOG_WARN("Failed to extract user name", K(arg), K(ret));
|
||||
} else {
|
||||
if (OB_FAIL(ObDropUserExecutor::build_fail_msg(failed_users, failed_hosts, fail_msg))) {
|
||||
LOG_WARN("Build fail msg error", K(arg), K(ret));
|
||||
} else {
|
||||
ret = OB_CANNOT_USER;
|
||||
LOG_USER_ERROR(
|
||||
OB_CANNOT_USER, (int)strlen("RENAME USER"), "RENAME USER", (int)fail_msg.length(), fail_msg.ptr());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Rename user completely success
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObAlterUserPrimaryZoneExecutor::execute(ObExecContext& ctx, ObAlterUserPrimaryZoneStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
ObString first_stmt;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
if (OB_ISNULL(session = ctx.get_my_session())) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "session is NULL");
|
||||
} else if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get task executor context failed", K(ret));
|
||||
} else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("get common rpc proxy failed", K(ret));
|
||||
} else if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
stmt.arg_.exec_tenant_id_ = session->get_effective_tenant_id();
|
||||
stmt.arg_.ddl_stmt_str_ = first_stmt;
|
||||
OZ(common_rpc_proxy->alter_database(stmt.arg_));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
129
src/sql/engine/cmd/ob_user_cmd_executor.h
Normal file
129
src/sql/engine/cmd/ob_user_cmd_executor.h
Normal file
@ -0,0 +1,129 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_ENGINE_CMD_USER_CMD_EXECUTOR_
|
||||
#define OCEANBASE_SQL_ENGINE_CMD_USER_CMD_EXECUTOR_
|
||||
#include "share/ob_define.h"
|
||||
#include "lib/string/ob_string.h"
|
||||
#include "lib/container/ob_array_serialization.h"
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace obrpc {
|
||||
class ObCommonRpcProxy;
|
||||
class ObCreateUserArg;
|
||||
class ObLockUserArg;
|
||||
class ObRenameUserArg;
|
||||
class ObDropUserArg;
|
||||
} // namespace obrpc
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObCreateUserStmt;
|
||||
class ObDropUserExecutor;
|
||||
class ObCreateUserExecutor {
|
||||
public:
|
||||
ObCreateUserExecutor()
|
||||
{}
|
||||
virtual ~ObCreateUserExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObCreateUserStmt& stmt);
|
||||
static int encrypt_passwd(
|
||||
const common::ObString& passwd, common::ObString& encrypted_passwd, char* enc_buf, int64_t buf_len);
|
||||
static int userinfo_extract_user_name(const common::ObIArray<share::schema::ObUserInfo>& user_infos,
|
||||
const common::ObIArray<int64_t>& index, common::ObIArray<common::ObString>& users,
|
||||
common::ObIArray<common::ObString>& hosts);
|
||||
|
||||
private:
|
||||
int create_user(obrpc::ObCommonRpcProxy* rpc_proxy, const obrpc::ObCreateUserArg& arg) const;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObCreateUserExecutor);
|
||||
};
|
||||
|
||||
class ObDropUserStmt;
|
||||
class ObDropUserExecutor {
|
||||
public:
|
||||
ObDropUserExecutor()
|
||||
{}
|
||||
virtual ~ObDropUserExecutor()
|
||||
{}
|
||||
static int build_fail_msg(const common::ObIArray<common::ObString>& users,
|
||||
const common::ObIArray<common::ObString>& hosts, common::ObSqlString& msg);
|
||||
static int string_array_index_extract(const common::ObIArray<common::ObString>& src_users,
|
||||
const common::ObIArray<common::ObString>& src_hosts, const common::ObIArray<int64_t>& index,
|
||||
common::ObIArray<common::ObString>& dst_users, common::ObIArray<common::ObString>& dst_hosts);
|
||||
int execute(ObExecContext& ctx, ObDropUserStmt& stmt);
|
||||
|
||||
private:
|
||||
int drop_user(obrpc::ObCommonRpcProxy* rpc_proxy, const obrpc::ObDropUserArg& arg);
|
||||
DISALLOW_COPY_AND_ASSIGN(ObDropUserExecutor);
|
||||
};
|
||||
|
||||
class ObLockUserStmt;
|
||||
class ObLockUserExecutor {
|
||||
public:
|
||||
ObLockUserExecutor()
|
||||
{}
|
||||
virtual ~ObLockUserExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObLockUserStmt& stmt);
|
||||
|
||||
private:
|
||||
int lock_user(obrpc::ObCommonRpcProxy* rpc_proxy, const obrpc::ObLockUserArg& arg);
|
||||
DISALLOW_COPY_AND_ASSIGN(ObLockUserExecutor);
|
||||
};
|
||||
|
||||
class ObAlterUserProfileStmt;
|
||||
class ObAlterUserProfileExecutor {
|
||||
private:
|
||||
int set_role_exec(ObExecContext& ctx, ObAlterUserProfileStmt& stmt);
|
||||
|
||||
public:
|
||||
ObAlterUserProfileExecutor()
|
||||
{}
|
||||
virtual ~ObAlterUserProfileExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObAlterUserProfileStmt& stmt);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ObAlterUserProfileExecutor);
|
||||
};
|
||||
|
||||
class ObRenameUserStmt;
|
||||
class ObRenameUserExecutor {
|
||||
public:
|
||||
ObRenameUserExecutor()
|
||||
{}
|
||||
virtual ~ObRenameUserExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObRenameUserStmt& stmt);
|
||||
|
||||
private:
|
||||
int rename_user(obrpc::ObCommonRpcProxy* rpc_proxy, const obrpc::ObRenameUserArg& arg);
|
||||
DISALLOW_COPY_AND_ASSIGN(ObRenameUserExecutor);
|
||||
};
|
||||
|
||||
class ObAlterUserPrimaryZoneStmt;
|
||||
class ObAlterUserPrimaryZoneExecutor {
|
||||
public:
|
||||
ObAlterUserPrimaryZoneExecutor()
|
||||
{}
|
||||
virtual ~ObAlterUserPrimaryZoneExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObAlterUserPrimaryZoneStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObAlterUserPrimaryZoneExecutor);
|
||||
};
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif // OCEANBASE_SQL_ENGINE_CMD_USER_CMD_EXECUTOR_
|
||||
871
src/sql/engine/cmd/ob_variable_set_executor.cpp
Normal file
871
src/sql/engine/cmd/ob_variable_set_executor.cpp
Normal file
@ -0,0 +1,871 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
|
||||
#include "lib/string/ob_sql_string.h"
|
||||
#include "lib/mysqlclient/ob_mysql_proxy.h"
|
||||
#include "common/sql_mode/ob_sql_mode_utils.h"
|
||||
#include "observer/ob_server_struct.h"
|
||||
#include "observer/ob_sql_client_decorator.h"
|
||||
#include "share/ob_i_sql_expression.h"
|
||||
#include "share/ob_schema_status_proxy.h"
|
||||
#include "share/ob_common_rpc_proxy.h"
|
||||
#include "share/object/ob_obj_cast.h"
|
||||
#include "share/inner_table/ob_inner_table_schema.h"
|
||||
#include "share/schema/ob_schema_utils.h"
|
||||
#include "sql/engine/cmd/ob_variable_set_executor.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/engine/ob_physical_plan.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/code_generator/ob_expr_generator_impl.h"
|
||||
#include "sql/code_generator/ob_column_index_provider.h"
|
||||
#include "sql/ob_sql_trans_control.h"
|
||||
#include "sql/ob_end_trans_callback.h"
|
||||
#include "lib/timezone/ob_oracle_format_models.h"
|
||||
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::share;
|
||||
using namespace oceanbase::share::schema;
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
|
||||
#define DEFINE_CAST_CTX() \
|
||||
ObCollationType cast_coll_type = CS_TYPE_INVALID; \
|
||||
if (NULL != ctx.get_my_session()) { \
|
||||
if (common::OB_SUCCESS != ctx.get_my_session()->get_collation_connection(cast_coll_type)) { \
|
||||
LOG_WARN("fail to get collation_connection"); \
|
||||
cast_coll_type = ObCharset::get_default_collation(ObCharset::get_default_charset()); \
|
||||
} else { \
|
||||
} \
|
||||
} else { \
|
||||
LOG_WARN("session is null"); \
|
||||
cast_coll_type = ObCharset::get_system_collation(); \
|
||||
} \
|
||||
const ObDataTypeCastParams dtc_params = ObBasicSessionInfo::create_dtc_params(ctx.get_my_session()); \
|
||||
ObCastCtx cast_ctx( \
|
||||
&calc_buf, &dtc_params, get_cur_time(ctx.get_physical_plan_ctx()), CM_NONE, cast_coll_type, (NULL));
|
||||
|
||||
ObVariableSetExecutor::ObVariableSetExecutor()
|
||||
{}
|
||||
|
||||
ObVariableSetExecutor::~ObVariableSetExecutor()
|
||||
{}
|
||||
|
||||
int ObVariableSetExecutor::execute(ObExecContext& ctx, ObVariableSetStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int ret_ac = OB_SUCCESS;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
ObMySQLProxy* sql_proxy = NULL;
|
||||
ObPhysicalPlanCtx* plan_ctx = NULL;
|
||||
if (OB_ISNULL(session = ctx.get_my_session()) || OB_ISNULL(sql_proxy = ctx.get_sql_proxy()) ||
|
||||
OB_ISNULL(plan_ctx = ctx.get_physical_plan_ctx())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session or sql proxy or physical plan ctx is NULL", K(ret), K(session), K(sql_proxy), K(plan_ctx));
|
||||
} else {
|
||||
ObPhysicalPlan phy_plan;
|
||||
ObPhysicalPlanCtx phy_plan_ctx(ctx.get_allocator());
|
||||
ObExprCtx expr_ctx;
|
||||
phy_plan_ctx.set_phy_plan(&phy_plan);
|
||||
phy_plan_ctx.set_last_insert_id_session(session->get_local_last_insert_id());
|
||||
const int64_t cur_time =
|
||||
plan_ctx->has_cur_time() ? plan_ctx->get_cur_time().get_timestamp() : ObTimeUtility::current_time();
|
||||
phy_plan_ctx.set_cur_time(cur_time, *session);
|
||||
|
||||
expr_ctx.phy_plan_ctx_ = &phy_plan_ctx;
|
||||
expr_ctx.my_session_ = session;
|
||||
expr_ctx.exec_ctx_ = &ctx;
|
||||
expr_ctx.calc_buf_ = &ctx.get_allocator();
|
||||
if (OB_ISNULL(expr_ctx.exec_ctx_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("expr_ctx.exec_ctx_ is NULL", K(ret));
|
||||
} else {
|
||||
expr_ctx.exec_ctx_->set_sql_proxy(sql_proxy);
|
||||
}
|
||||
ObVariableSetStmt::VariableSetNode tmp_node; // just for init node
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < stmt.get_variables_size(); ++i) {
|
||||
ObVariableSetStmt::VariableSetNode& node = tmp_node;
|
||||
if (OB_FAIL(stmt.get_variable_node(i, node))) {
|
||||
LOG_WARN("fail to get variable node", K(i), K(ret));
|
||||
} else {
|
||||
ObNewRow tmp_row;
|
||||
ObObj value_obj;
|
||||
ObBasicSysVar* sys_var = NULL;
|
||||
RowDesc row_desc;
|
||||
ObExprGeneratorImpl expr_gen(0, 0, NULL, row_desc);
|
||||
ObSqlExpression sql_expr(ctx.get_allocator(), 0);
|
||||
if (true == node.is_set_default_) {
|
||||
if (false == node.is_system_variable_) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("when reach here, node.is_system_variable_ must be true", K(ret));
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
if (OB_ISNULL(node.value_expr_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("node.value_expr_ is NULL", K(ret));
|
||||
} else {
|
||||
if ((!node.is_system_variable_) || (!is_strict_mode(session->get_sql_mode()))) {
|
||||
expr_ctx.cast_mode_ = CM_WARN_ON_FAIL;
|
||||
} else {
|
||||
}
|
||||
if (OB_FAIL(expr_gen.generate(*node.value_expr_, sql_expr))) {
|
||||
LOG_WARN("fail to fill sql expression", K(ret));
|
||||
} else if (FALSE_IT(phy_plan.set_regexp_op_count(expr_gen.get_cur_regexp_op_count()))) {
|
||||
} else if (FALSE_IT(phy_plan.set_like_op_count(expr_gen.get_cur_like_op_count()))) {
|
||||
} else if (OB_FAIL(sql_expr.calc(expr_ctx, tmp_row, value_obj))) {
|
||||
LOG_WARN("fail to calc value", K(ret), K(*node.value_expr_));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (false == node.is_system_variable_) {
|
||||
if (OB_FAIL(set_user_variable(value_obj, node.variable_name_, expr_ctx))) {
|
||||
LOG_WARN("set user variable failed", K(ret));
|
||||
}
|
||||
} else {
|
||||
ObSetVar set_var(node.variable_name_,
|
||||
node.set_scope_,
|
||||
node.is_set_default_,
|
||||
stmt.get_actual_tenant_id(),
|
||||
*expr_ctx.calc_buf_,
|
||||
*sql_proxy);
|
||||
ObObj out_obj;
|
||||
const bool is_set_stmt = true;
|
||||
if (OB_FAIL(session->get_sys_variable_by_name(node.variable_name_, sys_var))) {
|
||||
if (OB_ERR_SYS_VARIABLE_UNKNOWN == ret) {
|
||||
// session system variable not found, maybe latest data from proxy,
|
||||
// so search in __all_sys_variable first.
|
||||
const uint64_t tenant_id = session->get_effective_tenant_id();
|
||||
const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id);
|
||||
ObSQLClientRetryWeak sql_client_retry_weak(sql_proxy, exec_tenant_id, OB_ALL_SYS_VARIABLE_TID);
|
||||
ObObj tmp_val;
|
||||
ObSqlString sql;
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res)
|
||||
{
|
||||
sqlclient::ObMySQLResult* result = NULL;
|
||||
if (OB_FAIL(sql.assign_fmt("select 1 from %s where tenant_id=%lu and name='%.*s';",
|
||||
OB_ALL_SYS_VARIABLE_TNAME,
|
||||
ObSchemaUtils::get_extract_tenant_id(exec_tenant_id, tenant_id),
|
||||
node.variable_name_.length(),
|
||||
node.variable_name_.ptr()))) {
|
||||
LOG_WARN("assign sql string failed", K(ret));
|
||||
} else if (OB_FAIL(sql_client_retry_weak.read(res, exec_tenant_id, sql.ptr()))) {
|
||||
LOG_WARN("execute sql failed", K(sql), K(ret));
|
||||
} else if (OB_ISNULL(result = res.get_result())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to get sql result", K(ret));
|
||||
} else if (OB_FAIL(result->next())) {
|
||||
if (OB_ITER_END == ret) {
|
||||
// not found in inner table, means it is not a system variable
|
||||
ret = OB_ERR_SYS_VARIABLE_UNKNOWN;
|
||||
LOG_USER_ERROR(
|
||||
OB_ERR_SYS_VARIABLE_UNKNOWN, node.variable_name_.length(), node.variable_name_.ptr());
|
||||
} else {
|
||||
LOG_WARN("get result failed", K(ret));
|
||||
}
|
||||
} else {
|
||||
// found in __all_sys_variable, means it's caused by version compatibility.
|
||||
// return OB_SYS_VARS_MAYBE_DIFF_VERSION, set OB_SUCCESS later.
|
||||
ret = OB_SYS_VARS_MAYBE_DIFF_VERSION;
|
||||
LOG_INFO("try to set sys var from new version, ignore it", K(ret), K(node.variable_name_));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOG_WARN("fail to get system variable", K(ret), K(node.variable_name_));
|
||||
}
|
||||
} else if (OB_ISNULL(sys_var)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("sys_var is NULL", K(ret), K(node.variable_name_));
|
||||
} else if (!share::is_mysql_mode() && sys_var->is_mysql_only()) {
|
||||
// ignore set mysql only variables in oracle mode
|
||||
} else if (!share::is_oracle_mode() && sys_var->is_oracle_only()) {
|
||||
// ignore set oracle only variables in mysql mode
|
||||
} else {
|
||||
if (OB_FAIL(check_and_convert_sys_var(ctx, set_var, *sys_var, value_obj, out_obj, is_set_stmt))) {
|
||||
LOG_WARN("fail to check", K(ret), K(node), K(*sys_var), K(value_obj));
|
||||
} else if (FALSE_IT(value_obj = out_obj)) {
|
||||
} else if (OB_FAIL(cast_value(ctx,
|
||||
node,
|
||||
stmt.get_actual_tenant_id(),
|
||||
*expr_ctx.calc_buf_,
|
||||
*sys_var,
|
||||
value_obj,
|
||||
out_obj))) {
|
||||
LOG_WARN("fail to cast value", K(ret), K(node), K(*sys_var), K(value_obj));
|
||||
} else if (FALSE_IT(value_obj = out_obj)) {
|
||||
} else if (node.variable_name_ == OB_SV_AUTO_INCREMENT_INCREMENT ||
|
||||
node.variable_name_ == OB_SV_AUTO_INCREMENT_OFFSET) {
|
||||
if (OB_FAIL(process_auto_increment_hook(session->get_sql_mode(), node.variable_name_, value_obj))) {
|
||||
LOG_WARN("fail to process auto increment hook", K(ret));
|
||||
} else {
|
||||
}
|
||||
} else if (node.variable_name_ == OB_SV_LAST_INSERT_ID) {
|
||||
if (OB_FAIL(
|
||||
process_last_insert_id_hook(plan_ctx, session->get_sql_mode(), node.variable_name_, value_obj))) {
|
||||
LOG_WARN("fail to process auto increment hook", K(ret));
|
||||
} else {
|
||||
}
|
||||
} else if (ObSetVar::SET_SCOPE_GLOBAL == node.set_scope_ &&
|
||||
node.variable_name_ == OB_SV_STMT_PARALLEL_DEGREE) {
|
||||
const static int64_t PARALLEL_DEGREE_VALID_VALUE = 1;
|
||||
int64_t parallel_degree_set_val = -1;
|
||||
if (OB_FAIL(value_obj.get_int(parallel_degree_set_val))) {
|
||||
LOG_WARN("fail to get int64_t from value_obj", K(ret), K(value_obj));
|
||||
} else if (PARALLEL_DEGREE_VALID_VALUE != parallel_degree_set_val) {
|
||||
ret = OB_ERR_WRONG_VALUE_FOR_VAR;
|
||||
char buf[32];
|
||||
(void)databuff_printf(buf, 32, "%ld", parallel_degree_set_val);
|
||||
ObString value(buf);
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_VALUE_FOR_VAR,
|
||||
node.variable_name_.length(),
|
||||
node.variable_name_.ptr(),
|
||||
value.length(),
|
||||
value.ptr());
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (ObSetVar::SET_SCOPE_SESSION == node.set_scope_) {
|
||||
// handle autocommit case, must call before update_sys_variable,
|
||||
// because update_sys_variable will change value of ac.
|
||||
if (node.variable_name_ == OB_SV_AUTOCOMMIT) {
|
||||
if (OB_UNLIKELY(OB_SUCCESS != (ret_ac = process_session_autocommit_hook(ctx, value_obj)))) {
|
||||
LOG_WARN("fail to process session autocommit", K(ret), K(ret_ac));
|
||||
if (OB_ERR_WRONG_VALUE_FOR_VAR == ret_ac) {
|
||||
ret = ret_ac;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (set_var.var_name_ == OB_SV_READ_ONLY) {
|
||||
if (session->get_in_transaction()) {
|
||||
ret = OB_ERR_LOCK_OR_ACTIVE_TRANSACTION;
|
||||
|
||||
LOG_WARN("Can't execute the given command because "
|
||||
"you have active locked tables or an active transaction",
|
||||
K(ret));
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (set_var.var_name_ == OB_SV_COMPATIBILITY_MODE) {
|
||||
if (!(OB_SYS_TENANT_ID == session->get_effective_tenant_id()) || !GCONF.in_upgrade_mode()) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_WARN("Compatibility mode can be changed only under upgrade mode and system tenant",
|
||||
K(ret),
|
||||
K(session->get_effective_tenant_id()));
|
||||
LOG_USER_ERROR(
|
||||
OB_OP_NOT_ALLOW, "Compatibility mode be changed not under upgrade mode and system tenant");
|
||||
} else if (ObSetVar::SET_SCOPE_SESSION != set_var.set_scope_) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_WARN("Compatibility mode can be changed only under session scope",
|
||||
K(ret),
|
||||
K(session->get_effective_tenant_id()));
|
||||
LOG_USER_ERROR(OB_OP_NOT_ALLOW, "Compatibility mode be changed not in session scope");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && set_var.set_scope_ == ObSetVar::SET_SCOPE_GLOBAL) {
|
||||
if (OB_FAIL(update_global_variables(ctx, stmt, set_var, value_obj))) {
|
||||
LOG_WARN("failed to update global variables", K(ret));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && set_var.set_scope_ == ObSetVar::SET_SCOPE_SESSION) {
|
||||
if (OB_FAIL(sys_var->session_update(ctx, set_var, value_obj))) {
|
||||
LOG_WARN("fail to update", K(ret), K(*sys_var), K(set_var), K(value_obj));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(sys_var->update(ctx, set_var, value_obj))) {
|
||||
LOG_WARN("update sys var state failed", K(ret), K(set_var));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SYS_VARS_MAYBE_DIFF_VERSION == ret) {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCCESS != ret_ac) {
|
||||
ret = ret_ac;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetExecutor::set_user_variable(const ObObj& val, const ObString& variable_name, const ObExprCtx& expr_ctx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
// user defined tmp variable
|
||||
ObSQLSessionInfo* session = expr_ctx.my_session_;
|
||||
ObSessionVariable sess_var;
|
||||
if (OB_ISNULL(session)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session is null", K(ret));
|
||||
} else if (OB_FAIL(switch_to_session_variable(expr_ctx, val, sess_var))) {
|
||||
LOG_WARN("fail to stiwch to session variablee", K(ret), K(val));
|
||||
} else if (OB_FAIL(session->replace_user_variable(variable_name, sess_var))) {
|
||||
LOG_WARN("set variable to session plan failed", K(ret), K(variable_name));
|
||||
} else {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetExecutor::update_global_variables(
|
||||
ObExecContext& ctx, ObDDLStmt& stmt, const ObSetVar& set_var, const ObObj& val)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
obrpc::ObRpcOpts rpc_opt;
|
||||
ObSQLSessionInfo* session = NULL;
|
||||
ObTaskExecutorCtx* task_exec_ctx = NULL;
|
||||
obrpc::ObCommonRpcProxy* common_rpc_proxy = NULL;
|
||||
obrpc::ObModifySysVarArg& arg = static_cast<obrpc::ObModifySysVarArg&>(stmt.get_ddl_arg());
|
||||
ObString extra_var_name;
|
||||
ObString extra_var_value;
|
||||
ObString extra_val;
|
||||
ObString val_str;
|
||||
ObCollationType extra_coll_type = CS_TYPE_INVALID;
|
||||
char extra_var_value_buf[32] = {'\0'};
|
||||
int64_t pos = 0;
|
||||
bool should_update_extra_var = false;
|
||||
if (OB_ISNULL(session = ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session is NULL", K(ret));
|
||||
} else {
|
||||
arg.tenant_id_ = set_var.actual_tenant_id_;
|
||||
arg.exec_tenant_id_ = set_var.actual_tenant_id_;
|
||||
ObString first_stmt;
|
||||
if (OB_FAIL(stmt.get_first_stmt(first_stmt))) {
|
||||
LOG_WARN("fail to get first stmt", K(ret));
|
||||
} else {
|
||||
arg.ddl_stmt_str_ = first_stmt;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (set_var.var_name_ == OB_SV_COLLATION_SERVER || set_var.var_name_ == OB_SV_COLLATION_DATABASE ||
|
||||
set_var.var_name_ == OB_SV_COLLATION_CONNECTION) {
|
||||
ObString coll_str;
|
||||
int64_t coll_int64 = OB_INVALID_INDEX;
|
||||
if (OB_FAIL(val.get_int(coll_int64))) {
|
||||
LOG_WARN("get int from val failed", K(ret));
|
||||
} else if (OB_UNLIKELY(!ObCharset::is_valid_collation(coll_int64))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid collation", K(ret), K(coll_int64), K(val));
|
||||
} else if (FALSE_IT(coll_str = ObString::make_string(
|
||||
ObCharset::collation_name(static_cast<ObCollationType>(coll_int64))))) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(ObBasicSysVar::get_charset_var_and_val_by_collation(
|
||||
set_var.var_name_, coll_str, extra_var_name, extra_val, extra_coll_type))) {
|
||||
LOG_ERROR(
|
||||
"fail to get charset variable and value by collation", K(ret), K(set_var.var_name_), K(val), K(coll_str));
|
||||
} else if (OB_FAIL(databuff_printf(extra_var_value_buf,
|
||||
sizeof(extra_var_value_buf),
|
||||
pos,
|
||||
"%d",
|
||||
static_cast<int32_t>(extra_coll_type)))) {
|
||||
LOG_WARN("databuff printf failed", K(extra_coll_type), K(ret));
|
||||
} else {
|
||||
extra_var_value.assign(extra_var_value_buf, pos);
|
||||
should_update_extra_var = true;
|
||||
}
|
||||
} else if (set_var.var_name_ == OB_SV_CHARACTER_SET_SERVER || set_var.var_name_ == OB_SV_CHARACTER_SET_DATABASE ||
|
||||
set_var.var_name_ == OB_SV_CHARACTER_SET_CONNECTION) {
|
||||
ObString cs_str;
|
||||
int64_t coll_int64 = OB_INVALID_INDEX;
|
||||
if (OB_FAIL(val.get_int(coll_int64))) {
|
||||
LOG_WARN("get int from value failed", K(ret));
|
||||
} else if (OB_UNLIKELY(!ObCharset::is_valid_collation(coll_int64))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid collation", K(ret), K(coll_int64));
|
||||
} else if (FALSE_IT(cs_str = ObString::make_string(ObCharset::charset_name(
|
||||
ObCharset::charset_type_by_coll(static_cast<ObCollationType>(coll_int64)))))) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(ObBasicSysVar::get_collation_var_and_val_by_charset(
|
||||
set_var.var_name_, cs_str, extra_var_name, extra_val, extra_coll_type))) {
|
||||
LOG_ERROR(
|
||||
"fail to get collation variable and value by charset", K(ret), K(set_var.var_name_), K(val), K(cs_str));
|
||||
} else if (OB_FAIL(databuff_printf(extra_var_value_buf,
|
||||
sizeof(extra_var_value_buf),
|
||||
pos,
|
||||
"%d",
|
||||
static_cast<int32_t>(extra_coll_type)))) {
|
||||
LOG_WARN("databuff printf failed", K(extra_coll_type), K(ret));
|
||||
} else {
|
||||
extra_var_value.assign(extra_var_value_buf, pos);
|
||||
should_update_extra_var = true;
|
||||
}
|
||||
} else if (set_var.var_name_ == OB_SV_NLS_DATE_FORMAT || set_var.var_name_ == OB_SV_NLS_TIMESTAMP_FORMAT ||
|
||||
set_var.var_name_ == OB_SV_NLS_TIMESTAMP_TZ_FORMAT) {
|
||||
ObString format;
|
||||
if (OB_UNLIKELY(val.is_null_oracle())) {
|
||||
ret = OB_INVALID_DATE_FORMAT;
|
||||
LOG_WARN("date format not recognized", K(ret), K(set_var.var_name_), K(val));
|
||||
} else if (OB_FAIL(val.get_varchar(format))) {
|
||||
LOG_WARN("fail get varchar", K(val), K(ret));
|
||||
} else {
|
||||
int64_t nls_enum = ObNLSFormatEnum::NLS_DATE;
|
||||
ObDTMode mode = DT_TYPE_DATETIME;
|
||||
if (set_var.var_name_ == OB_SV_NLS_TIMESTAMP_FORMAT) {
|
||||
mode |= DT_TYPE_ORACLE;
|
||||
nls_enum = ObNLSFormatEnum::NLS_TIMESTAMP;
|
||||
} else if (set_var.var_name_ == OB_SV_NLS_TIMESTAMP_TZ_FORMAT) {
|
||||
mode |= DT_TYPE_ORACLE;
|
||||
mode |= DT_TYPE_TIMEZONE;
|
||||
nls_enum = ObNLSFormatEnum::NLS_TIMESTAMP_TZ;
|
||||
}
|
||||
ObSEArray<ObDFMElem, ObDFMUtil::COMMON_ELEMENT_NUMBER> dfm_elems;
|
||||
ObBitSet<ObDFMFlag::MAX_FLAG_NUMBER> elem_flags;
|
||||
// 1. parse and check semantic of format string
|
||||
if (OB_FAIL(ObDFMUtil::parse_datetime_format_string(format, dfm_elems))) {
|
||||
LOG_WARN("fail to parse oracle datetime format string", K(ret), K(format));
|
||||
} else if (OB_FAIL(ObDFMUtil::check_semantic(dfm_elems, elem_flags, mode))) {
|
||||
LOG_WARN("check semantic of format string failed", K(ret), K(format));
|
||||
}
|
||||
}
|
||||
} else if (set_var.var_name_ == OB_SV_LOG_LEVEL) {
|
||||
ObString log_level;
|
||||
if (OB_FAIL(val.get_varchar(log_level))) {
|
||||
LOG_WARN("fail get varchar", K(val), K(ret));
|
||||
} else if (0 == log_level.case_compare("disabled")) {
|
||||
// allowed for variables
|
||||
} else if (OB_FAIL(OB_LOGGER.parse_check(log_level.ptr(), log_level.length()))) {
|
||||
LOG_WARN("Log level parse check error", K(log_level), K(ret));
|
||||
}
|
||||
} else if (set_var.var_name_ == OB_SV_TRANSACTION_ISOLATION) {
|
||||
extra_var_name = ObString::make_string(OB_SV_TX_ISOLATION);
|
||||
should_update_extra_var = true;
|
||||
if (OB_FAIL(val.get_varchar(extra_var_value))) {
|
||||
LOG_WARN("fail get varchar", K(val), K(ret));
|
||||
}
|
||||
} else if (set_var.var_name_ == OB_SV_TX_ISOLATION) {
|
||||
extra_var_name = ObString::make_string(OB_SV_TRANSACTION_ISOLATION);
|
||||
should_update_extra_var = true;
|
||||
if (OB_FAIL(val.get_varchar(extra_var_value))) {
|
||||
LOG_WARN("fail get varchar", K(val), K(ret));
|
||||
}
|
||||
} else if (set_var.var_name_ == OB_SV_TX_READ_ONLY) {
|
||||
int64_t extra_var_values = -1;
|
||||
extra_var_name = ObString::make_string(OB_SV_TRANSACTION_READ_ONLY);
|
||||
if (OB_FAIL(val.get_int(extra_var_values))) {
|
||||
LOG_WARN("fail get int", K(val), K(ret));
|
||||
} else if (OB_FAIL(databuff_printf(extra_var_value_buf,
|
||||
sizeof(extra_var_value_buf),
|
||||
pos,
|
||||
"%d",
|
||||
static_cast<int32_t>(extra_var_values)))) {
|
||||
LOG_WARN("databuff printf failed", K(extra_var_values), K(ret));
|
||||
} else {
|
||||
extra_var_value.assign(extra_var_value_buf, pos);
|
||||
should_update_extra_var = true;
|
||||
}
|
||||
} else if (set_var.var_name_ == OB_SV_TRANSACTION_READ_ONLY) {
|
||||
extra_var_name = ObString::make_string(OB_SV_TX_READ_ONLY);
|
||||
int64_t extra_var_values = -1;
|
||||
if (OB_FAIL(val.get_int(extra_var_values))) {
|
||||
LOG_WARN("fail get int", K(val), K(ret));
|
||||
} else if (OB_FAIL(databuff_printf(extra_var_value_buf,
|
||||
sizeof(extra_var_value_buf),
|
||||
pos,
|
||||
"%d",
|
||||
static_cast<int32_t>(extra_var_values)))) {
|
||||
LOG_WARN("databuff printf failed", K(extra_var_values), K(ret));
|
||||
} else {
|
||||
extra_var_value.assign(extra_var_value_buf, pos);
|
||||
should_update_extra_var = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && should_update_extra_var) {
|
||||
ObSysVarSchema sysvar_schema;
|
||||
if (OB_FAIL(sysvar_schema.set_name(extra_var_name))) {
|
||||
LOG_WARN("set sysvar schema name failed", K(ret));
|
||||
} else if (OB_FAIL(sysvar_schema.set_value(extra_var_value))) {
|
||||
LOG_WARN("set sysvar schema value failed", K(ret));
|
||||
} else {
|
||||
sysvar_schema.set_tenant_id(arg.tenant_id_);
|
||||
if (OB_FAIL(arg.sys_var_list_.push_back(sysvar_schema))) {
|
||||
LOG_WARN("store sys var to array failed", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
ObExprCtx expr_ctx;
|
||||
expr_ctx.exec_ctx_ = &ctx;
|
||||
expr_ctx.calc_buf_ = &set_var.calc_buf_;
|
||||
expr_ctx.my_session_ = ctx.get_my_session();
|
||||
EXPR_DEFINE_CAST_CTX(expr_ctx, CM_NONE);
|
||||
EXPR_GET_VARCHAR_V2(val, val_str);
|
||||
ObSysVarSchema sysvar_schema;
|
||||
if (OB_UNLIKELY(val_str.length() > OB_MAX_SYS_VAR_VAL_LENGTH)) {
|
||||
ret = OB_SIZE_OVERFLOW;
|
||||
LOG_WARN("set sysvar value is overflow",
|
||||
"max length",
|
||||
OB_MAX_SYS_VAR_VAL_LENGTH,
|
||||
"value length",
|
||||
val_str.length(),
|
||||
"name",
|
||||
set_var.var_name_,
|
||||
"value",
|
||||
val_str);
|
||||
} else if (OB_FAIL(sysvar_schema.set_name(set_var.var_name_))) {
|
||||
LOG_WARN("set sysvar schema name failed", K(ret));
|
||||
} else if (OB_FAIL(sysvar_schema.set_value(val_str))) {
|
||||
LOG_WARN("set sysvar schema value failed", K(ret));
|
||||
} else {
|
||||
sysvar_schema.set_tenant_id(arg.tenant_id_);
|
||||
if (OB_FAIL(arg.sys_var_list_.push_back(sysvar_schema))) {
|
||||
LOG_WARN("store sys var to array failed", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx)) ||
|
||||
OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) {
|
||||
ret = OB_NOT_INIT;
|
||||
LOG_WARN("task exec ctx or common rpc proxy is NULL", K(ret), K(task_exec_ctx), K(common_rpc_proxy));
|
||||
} else if (OB_FAIL(common_rpc_proxy->modify_system_variable(arg))) {
|
||||
LOG_WARN("rpc proxy alter system variable failed", K(ret));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetExecutor::check_and_convert_sys_var(ObExecContext& ctx, const ObSetVar& set_var,
|
||||
ObBasicSysVar& sys_var, const ObObj& in_val, ObObj& out_val, bool is_set_stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
// OB_ASSERT(true == var_node.is_system_variable_);
|
||||
|
||||
// can't set collation_connection to utf16
|
||||
if (OB_SUCC(ret)) {
|
||||
if ((0 == set_var.var_name_.case_compare(OB_SV_CHARACTER_SET_CLIENT) ||
|
||||
0 == set_var.var_name_.case_compare(OB_SV_CHARACTER_SET_CONNECTION) ||
|
||||
0 == set_var.var_name_.case_compare(OB_SV_CHARACTER_SET_RESULTS) ||
|
||||
0 == set_var.var_name_.case_compare(OB_SV_COLLATION_CONNECTION)) &&
|
||||
(in_val.get_string().prefix_match_ci("utf16"))) {
|
||||
ret = OB_ERR_WRONG_VALUE_FOR_VAR;
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_VALUE_FOR_VAR,
|
||||
set_var.var_name_.length(),
|
||||
set_var.var_name_.ptr(),
|
||||
in_val.get_string().length(),
|
||||
in_val.get_string().ptr());
|
||||
}
|
||||
}
|
||||
|
||||
// check readonly
|
||||
if (is_set_stmt && sys_var.is_readonly()) {
|
||||
if (sys_var.is_with_upgrade() && GCONF.in_upgrade_mode()) {
|
||||
// do nothing ...
|
||||
} else {
|
||||
ret = OB_ERR_INCORRECT_GLOBAL_LOCAL_VAR;
|
||||
LOG_USER_ERROR(OB_ERR_INCORRECT_GLOBAL_LOCAL_VAR,
|
||||
set_var.var_name_.length(),
|
||||
set_var.var_name_.ptr(),
|
||||
(int)strlen("read only"),
|
||||
"read only");
|
||||
}
|
||||
}
|
||||
|
||||
// check scope
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (ObSetVar::SET_SCOPE_GLOBAL == set_var.set_scope_ && !sys_var.is_global_scope()) {
|
||||
ret = OB_ERR_LOCAL_VARIABLE;
|
||||
LOG_USER_ERROR(OB_ERR_LOCAL_VARIABLE, set_var.var_name_.length(), set_var.var_name_.ptr());
|
||||
} else if (ObSetVar::SET_SCOPE_SESSION == set_var.set_scope_ && !sys_var.is_session_scope()) {
|
||||
ret = OB_ERR_GLOBAL_VARIABLE;
|
||||
LOG_USER_ERROR(OB_ERR_GLOBAL_VARIABLE, set_var.var_name_.length(), set_var.var_name_.ptr());
|
||||
}
|
||||
|
||||
// check update type and value
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_SUCCESS != (ret = sys_var.check_update_type(set_var, in_val))) {
|
||||
if (OB_ERR_WRONG_TYPE_FOR_VAR == ret) {
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_TYPE_FOR_VAR, set_var.var_name_.length(), set_var.var_name_.ptr());
|
||||
} else {
|
||||
LOG_WARN("fail to check update type", K(ret));
|
||||
}
|
||||
} else if (OB_FAIL(sys_var.check_and_convert(ctx, set_var, in_val, out_val))) {
|
||||
if (OB_ERR_WRONG_TYPE_FOR_VAR == ret) {
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_TYPE_FOR_VAR, set_var.var_name_.length(), set_var.var_name_.ptr());
|
||||
} else {
|
||||
LOG_WARN("fail to check value", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
// do not support modify now
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (share::is_oracle_mode() && set_var.var_name_.prefix_match("nls_")) {
|
||||
static const common::ObString DEFAULT_VALUE_LANGUAGE("AMERICAN");
|
||||
static const common::ObString DEFAULT_VALUE_TERRITORY("AMERICA");
|
||||
static const common::ObString DEFAULT_VALUE_SORT("BINARY");
|
||||
static const common::ObString DEFAULT_VALUE_COMP("BINARY");
|
||||
static const common::ObString DEFAULT_VALUE_NCHAR_CHARACTERSET("AL16UTF16");
|
||||
static const common::ObString DEFAULT_VALUE_DATE_LANGUAGE("AMERICAN");
|
||||
static const common::ObString DEFAULT_VALUE_NCHAR_CONV_EXCP("FALSE");
|
||||
static const common::ObString DEFAULT_VALUE_CALENDAR("GREGORIAN");
|
||||
static const common::ObString DEFAULT_VALUE_NUMERIC_CHARACTERS(".,");
|
||||
static const common::ObString DEFAULT_VALUE_CURRENCY("$");
|
||||
static const common::ObString DEFAULT_VALUE_ISO_CURRENCY("AMERICA");
|
||||
static const common::ObString DEFAULT_VALUE_DUAL_CURRENCY("$");
|
||||
|
||||
const ObString new_value = out_val.get_string();
|
||||
if ((set_var.var_name_ == OB_SV_NLS_LANGUAGE && new_value.case_compare(DEFAULT_VALUE_LANGUAGE) != 0) ||
|
||||
(set_var.var_name_ == OB_SV_NLS_TERRITORY && new_value.case_compare(DEFAULT_VALUE_TERRITORY) != 0) ||
|
||||
(set_var.var_name_ == OB_SV_NLS_SORT && new_value.case_compare(DEFAULT_VALUE_SORT) != 0) ||
|
||||
(set_var.var_name_ == OB_SV_NLS_COMP && new_value.case_compare(DEFAULT_VALUE_COMP) != 0) ||
|
||||
(set_var.var_name_ == OB_SV_NLS_CHARACTERSET) ||
|
||||
(set_var.var_name_ == OB_SV_NLS_NCHAR_CHARACTERSET &&
|
||||
new_value.case_compare(DEFAULT_VALUE_NCHAR_CHARACTERSET) != 0) ||
|
||||
(set_var.var_name_ == OB_SV_NLS_DATE_LANGUAGE && new_value.case_compare(DEFAULT_VALUE_DATE_LANGUAGE) != 0) ||
|
||||
(set_var.var_name_ == OB_SV_NLS_NCHAR_CONV_EXCP &&
|
||||
new_value.case_compare(DEFAULT_VALUE_NCHAR_CONV_EXCP) != 0) ||
|
||||
(set_var.var_name_ == OB_SV_NLS_CALENDAR && new_value.case_compare(DEFAULT_VALUE_CALENDAR) != 0) ||
|
||||
(set_var.var_name_ == OB_SV_NLS_NUMERIC_CHARACTERS &&
|
||||
new_value.case_compare(DEFAULT_VALUE_NUMERIC_CHARACTERS) != 0) ||
|
||||
(set_var.var_name_ == OB_SV_NLS_CURRENCY && new_value.case_compare(DEFAULT_VALUE_CURRENCY) != 0) ||
|
||||
(set_var.var_name_ == OB_SV_NLS_ISO_CURRENCY && new_value.case_compare(DEFAULT_VALUE_ISO_CURRENCY) != 0) ||
|
||||
(set_var.var_name_ == OB_SV_NLS_DUAL_CURRENCY && new_value.case_compare(DEFAULT_VALUE_DUAL_CURRENCY) != 0)) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("not support modify this variables now", K(set_var), K(new_value), K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetExecutor::cast_value(ObExecContext& ctx, const ObVariableSetStmt::VariableSetNode& var_node,
|
||||
uint64_t actual_tenant_id, ObIAllocator& calc_buf, const ObBasicSysVar& sys_var, const ObObj& in_val,
|
||||
ObObj& out_val)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(GCTX.schema_service_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("schema_service_ is null");
|
||||
} else if (OB_ISNULL(ctx.get_my_session())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("my session is null");
|
||||
} else if (var_node.is_set_default_) {
|
||||
uint64_t tenant_id = actual_tenant_id;
|
||||
if (ObSetVar::SET_SCOPE_SESSION == var_node.set_scope_) {
|
||||
ObSchemaGetterGuard schema_guard;
|
||||
const ObSysVarSchema* var_schema = NULL;
|
||||
const ObDataTypeCastParams dtc_params = ObBasicSessionInfo::create_dtc_params(ctx.get_my_session());
|
||||
if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(tenant_id, schema_guard))) {
|
||||
LOG_WARN("get schema guard failed", K(ret));
|
||||
} else if (OB_FAIL(schema_guard.get_tenant_system_variable(tenant_id, var_node.variable_name_, var_schema))) {
|
||||
LOG_WARN("get tenant system variable failed", K(ret), K(tenant_id), K(var_node.variable_name_));
|
||||
} else if (OB_FAIL(var_schema->get_value(&calc_buf, dtc_params, out_val))) {
|
||||
LOG_WARN("get value from sysvar schema failed", K(ret));
|
||||
}
|
||||
} else if (ObSetVar::SET_SCOPE_GLOBAL == var_node.set_scope_) {
|
||||
const ObObj& def_val = sys_var.get_global_default_value();
|
||||
DEFINE_CAST_CTX();
|
||||
if (OB_FAIL(ObObjCaster::to_type(sys_var.get_data_type(), cast_ctx, def_val, out_val))) {
|
||||
LOG_ERROR("failed to cast object", K(ret), K(var_node.variable_name_), K(def_val), K(sys_var.get_data_type()));
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid set scope", K(ret), K(var_node.set_scope_));
|
||||
}
|
||||
} else if (ObNullType == in_val.get_type()) {
|
||||
out_val = in_val;
|
||||
} else {
|
||||
DEFINE_CAST_CTX();
|
||||
if (OB_FAIL(ObObjCaster::to_type(sys_var.get_data_type(), cast_ctx, in_val, out_val))) {
|
||||
LOG_WARN("failed to cast object", K(ret), K(var_node.variable_name_), K(in_val), K(sys_var.get_data_type()));
|
||||
} else {
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetExecutor::process_session_autocommit_hook(ObExecContext& exec_ctx, const ObObj& val)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* my_session = GET_MY_SESSION(exec_ctx);
|
||||
if (OB_ISNULL(my_session)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session is NULL", K(ret));
|
||||
} else {
|
||||
int64_t autocommit = 0;
|
||||
bool in_trans = my_session->get_in_transaction();
|
||||
bool ac = true;
|
||||
|
||||
if (OB_FAIL(my_session->get_autocommit(ac))) {
|
||||
LOG_WARN("fail to get autocommit", K(ret));
|
||||
} else if (OB_FAIL(val.get_int(autocommit))) {
|
||||
LOG_WARN("fail get commit val", K(val), K(ret));
|
||||
} else if (0 != autocommit && 1 != autocommit) {
|
||||
const char* autocommit_str = to_cstring(autocommit);
|
||||
ret = OB_ERR_WRONG_VALUE_FOR_VAR;
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_VALUE_FOR_VAR,
|
||||
(int)strlen(OB_SV_AUTOCOMMIT),
|
||||
OB_SV_AUTOCOMMIT,
|
||||
(int)strlen(autocommit_str),
|
||||
autocommit_str);
|
||||
} else {
|
||||
if (false == ac && true == in_trans && 1 == autocommit) {
|
||||
ObEndTransSyncCallback callback;
|
||||
const bool is_rollback = false;
|
||||
if (OB_FAIL(callback.init(&(my_session->get_trans_desc()), my_session))) {
|
||||
LOG_WARN("fail init callback", K(ret));
|
||||
} else {
|
||||
int wait_ret = OB_SUCCESS;
|
||||
if (OB_FAIL(ObSqlTransControl::implicit_end_trans(
|
||||
exec_ctx, is_rollback, callback))) { // implicit commit, no rollback
|
||||
LOG_WARN("fail end implicit trans", K(is_rollback), K(ret));
|
||||
}
|
||||
if (OB_UNLIKELY(OB_SUCCESS != (wait_ret = callback.wait()))) {
|
||||
LOG_WARN("sync end trans callback return an error!",
|
||||
K(ret),
|
||||
K(wait_ret),
|
||||
K(is_rollback),
|
||||
K(my_session->get_trans_desc()));
|
||||
}
|
||||
ret = OB_SUCCESS != ret ? ret : wait_ret;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetExecutor::process_auto_increment_hook(const ObSQLMode sql_mode, const ObString var_name, ObObj& val)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
uint64_t auto_increment = 0;
|
||||
if (OB_FAIL(val.get_uint64(auto_increment))) {
|
||||
LOG_WARN("fail get auto_increment value", K(ret), K(val));
|
||||
} else {
|
||||
if (SMO_STRICT_ALL_TABLES & sql_mode) {
|
||||
if (auto_increment <= 0 || auto_increment > UINT16_MAX) {
|
||||
char auto_increment_str[OB_CAST_TO_VARCHAR_MAX_LENGTH];
|
||||
int length = snprintf(auto_increment_str, OB_CAST_TO_VARCHAR_MAX_LENGTH, "%lu", auto_increment);
|
||||
if (length < 0 || length >= OB_CAST_TO_VARCHAR_MAX_LENGTH) {
|
||||
length = OB_CAST_TO_VARCHAR_MAX_LENGTH - 1;
|
||||
auto_increment_str[length] = '\0';
|
||||
}
|
||||
ret = OB_ERR_WRONG_VALUE_FOR_VAR;
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_VALUE_FOR_VAR, var_name.length(), var_name.ptr(), length, auto_increment_str);
|
||||
}
|
||||
} else {
|
||||
if (auto_increment <= 0) {
|
||||
auto_increment = 1;
|
||||
// should generate warning message
|
||||
// SQL_ENG_LOG(WARN, "Truncated incorrect value");
|
||||
} else if (auto_increment > UINT16_MAX) {
|
||||
auto_increment = UINT16_MAX;
|
||||
// should generate warning message
|
||||
// SQL_ENG_LOG(WARN, "Truncated incorrect value");
|
||||
}
|
||||
val.set_uint64(auto_increment);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetExecutor::process_last_insert_id_hook(
|
||||
ObPhysicalPlanCtx* plan_ctx, const ObSQLMode sql_mode, const ObString var_name, ObObj& val)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t value = 0;
|
||||
uint64_t unsigned_value = 0;
|
||||
if (OB_ISNULL(plan_ctx)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("plan ctx is NULL", K(ret));
|
||||
} else if (OB_FAIL(val.get_int(value))) {
|
||||
if (OB_FAIL(val.get_uint64(unsigned_value))) {
|
||||
ret = OB_ERR_WRONG_TYPE_FOR_VAR;
|
||||
LOG_WARN("failed to get value", K(val), K(ret));
|
||||
}
|
||||
} else {
|
||||
if (SMO_STRICT_ALL_TABLES & sql_mode) {
|
||||
if (value < 0) {
|
||||
char auto_increment_str[OB_CAST_TO_VARCHAR_MAX_LENGTH];
|
||||
int32_t length = snprintf(auto_increment_str, OB_CAST_TO_VARCHAR_MAX_LENGTH, "%ld", value);
|
||||
if (length < 0 || length >= OB_CAST_TO_VARCHAR_MAX_LENGTH) {
|
||||
length = OB_CAST_TO_VARCHAR_MAX_LENGTH - 1;
|
||||
auto_increment_str[length] = '\0';
|
||||
}
|
||||
ret = OB_ERR_WRONG_VALUE_FOR_VAR;
|
||||
LOG_USER_ERROR(OB_ERR_WRONG_VALUE_FOR_VAR, var_name.length(), var_name.ptr(), length, auto_increment_str);
|
||||
}
|
||||
} else {
|
||||
if (value < 0) {
|
||||
value = 0;
|
||||
// should generate warning message
|
||||
// SQL_ENG_LOG(WARN, "Truncated incorrect value");
|
||||
}
|
||||
val.set_int(value);
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (0 != unsigned_value) {
|
||||
plan_ctx->set_last_insert_id_session(unsigned_value);
|
||||
} else {
|
||||
plan_ctx->set_last_insert_id_session(static_cast<uint64_t>(value));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObVariableSetExecutor::switch_to_session_variable(
|
||||
const ObExprCtx& expr_ctx, const ObObj& value, ObSessionVariable& sess_var)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (ob_is_temporal_type(value.get_type())) { // switch the meta type and value type
|
||||
EXPR_DEFINE_CAST_CTX(expr_ctx, CM_NONE);
|
||||
ObObj obj_tmp;
|
||||
const ObObj* res_obj_ptr = NULL;
|
||||
if (OB_FAIL(ObObjCaster::to_type(ObVarcharType, cast_ctx, value, obj_tmp, res_obj_ptr))) {
|
||||
LOG_WARN("failed to cast object to ObVarcharType ", K(ret), K(value));
|
||||
} else if (OB_ISNULL(res_obj_ptr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("res_obj_ptr is NULL", K(ret));
|
||||
} else {
|
||||
sess_var.value_.set_varchar(res_obj_ptr->get_varchar());
|
||||
sess_var.meta_.set_collation_level(CS_LEVEL_IMPLICIT);
|
||||
sess_var.meta_.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset()));
|
||||
sess_var.meta_.set_varchar();
|
||||
}
|
||||
} else if (ObNullType == value.get_type()) { // switch the meta type only
|
||||
sess_var.value_.set_null();
|
||||
sess_var.meta_.set_collation_level(CS_LEVEL_IMPLICIT);
|
||||
sess_var.meta_.set_collation_type(CS_TYPE_BINARY);
|
||||
} else { // won't switch
|
||||
sess_var.value_ = value;
|
||||
sess_var.meta_.set_type(value.get_type());
|
||||
sess_var.meta_.set_scale(value.get_scale());
|
||||
sess_var.meta_.set_collation_level(CS_LEVEL_IMPLICIT);
|
||||
sess_var.meta_.set_collation_type(value.get_collation_type());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef DEFINE_CAST_CTX
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
60
src/sql/engine/cmd/ob_variable_set_executor.h
Normal file
60
src/sql/engine/cmd/ob_variable_set_executor.h
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_ENGINE_CMD_OB_VARIABLE_SET_EXECUTOR_
|
||||
#define OCEANBASE_SQL_ENGINE_CMD_OB_VARIABLE_SET_EXECUTOR_
|
||||
#include "sql/resolver/cmd/ob_variable_set_stmt.h"
|
||||
#include "share/ob_define.h"
|
||||
#include "sql/session/ob_session_val_map.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
class ObIAllocator;
|
||||
class ObExprCtx;
|
||||
namespace sqlclient {
|
||||
class ObMySQLProxy;
|
||||
}
|
||||
} // namespace common
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObSQLSessionInfo;
|
||||
class ObPhysicalPlanCtx;
|
||||
class ObVariableSetExecutor {
|
||||
public:
|
||||
ObVariableSetExecutor();
|
||||
virtual ~ObVariableSetExecutor();
|
||||
int execute(ObExecContext& ctx, ObVariableSetStmt& stmt);
|
||||
static int check_and_convert_sys_var(ObExecContext& ctx, const share::ObSetVar& set_var,
|
||||
share::ObBasicSysVar& sys_var, const common::ObObj& in_val, common::ObObj& out_val, bool is_set_stmt);
|
||||
static int set_user_variable(
|
||||
const common::ObObj& val, const common::ObString& name, const common::ObExprCtx& expr_ctx);
|
||||
static int cast_value(ObExecContext& ctx, const ObVariableSetStmt::VariableSetNode& var_node,
|
||||
uint64_t actual_tenant_id, common::ObIAllocator& calc_buf, const share::ObBasicSysVar& sys_val,
|
||||
const common::ObObj& in_val, common::ObObj& out_val);
|
||||
static int switch_to_session_variable(
|
||||
const common::ObExprCtx& expr_ctx, const common::ObObj& value, ObSessionVariable& sess_var);
|
||||
|
||||
private:
|
||||
int process_session_autocommit_hook(ObExecContext& exec_ctx, const common::ObObj& val);
|
||||
int process_auto_increment_hook(const ObSQLMode sql_mode, const common::ObString var_name, common::ObObj& val);
|
||||
int process_last_insert_id_hook(
|
||||
ObPhysicalPlanCtx* plan_ctx, const ObSQLMode sql_mode, const common::ObString var_name, common::ObObj& val);
|
||||
|
||||
int update_global_variables(
|
||||
ObExecContext& ctx, ObDDLStmt& stmt, const share::ObSetVar& set_var, const common::ObObj& value_obj);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObVariableSetExecutor);
|
||||
};
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
#endif /* OCEANBASE_SQL_ENGINE_CMD_OB_VARIABLE_SET_EXECUTOR_ */
|
||||
364
src/sql/engine/cmd/ob_xa_executor.cpp
Normal file
364
src/sql/engine/cmd/ob_xa_executor.cpp
Normal file
@ -0,0 +1,364 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#define USING_LOG_PREFIX SQL_ENG
|
||||
#include "sql/engine/cmd/ob_xa_executor.h"
|
||||
#include "share/ob_errno.h"
|
||||
#include "share/ob_define.h"
|
||||
#include "sql/resolver/xa/ob_xa_stmt.h"
|
||||
#include "sql/ob_sql_trans_control.h"
|
||||
#include "storage/transaction/ob_trans_define.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/executor/ob_task_executor_ctx.h"
|
||||
#include "storage/ob_partition_service.h"
|
||||
|
||||
namespace oceanbase {
|
||||
using namespace common;
|
||||
using namespace transaction;
|
||||
namespace sql {
|
||||
|
||||
static inline void init_start_trans_param(
|
||||
ObSQLSessionInfo* session, ObTaskExecutorCtx& task_exec_ctx, transaction::ObStartTransParam& param)
|
||||
{
|
||||
param.set_access_mode(transaction::ObTransAccessMode::READ_WRITE);
|
||||
param.set_type(session->get_trans_type());
|
||||
param.set_isolation(session->get_tx_isolation());
|
||||
param.set_cluster_version(task_exec_ctx.get_min_cluster_version());
|
||||
param.set_inner_trans(session->is_inner());
|
||||
}
|
||||
|
||||
int ObXaStartExecutor::execute(ObExecContext& ctx, ObXaStartStmt& stmt)
|
||||
{
|
||||
int ret = OB_NOT_SUPPORTED;
|
||||
UNUSED(ctx);
|
||||
UNUSED(stmt);
|
||||
return ret;
|
||||
/*
|
||||
int ret = OB_SUCCESS;
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
ObPhysicalPlanCtx *plan_ctx = GET_PHY_PLAN_CTX(ctx);
|
||||
ObSQLSessionInfo *my_session = GET_MY_SESSION(ctx);
|
||||
ObTaskExecutorCtx &task_exec_ctx = ctx.get_task_exec_ctx();
|
||||
storage::ObPartitionService *ps = nullptr;
|
||||
int32_t xa_trans_state = ObXATransState::NON_EXISTING;
|
||||
ObTransDesc &trans_desc = my_session->get_trans_desc();
|
||||
|
||||
if (OB_ISNULL(plan_ctx) || OB_ISNULL(my_session)
|
||||
|| OB_ISNULL(ps = task_exec_ctx.get_partition_service())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid param", K(ret), K(plan_ctx), K(my_session));
|
||||
} else if (OB_FAIL(ps->get_xa_trans_state(xa_trans_state, trans_desc))) {
|
||||
LOG_WARN("get xa trans state failed", K(ret));
|
||||
} else if (ObXATransState::NON_EXISTING != xa_trans_state) {
|
||||
ret = OB_TRANS_XA_RMFAIL;
|
||||
LOG_USER_ERROR(OB_TRANS_XA_RMFAIL, ObXATransState::to_string(xa_trans_state));
|
||||
LOG_WARN("invalid xa state", K(ret), K(xa_trans_state));
|
||||
} else if (my_session->get_in_transaction()) {
|
||||
ret = OB_TRANS_XA_OUTSIDE;
|
||||
LOG_WARN("already start trans", K(ret));
|
||||
} else {
|
||||
transaction::ObStartTransParam &start_trans_param = plan_ctx->get_start_trans_param();
|
||||
init_start_trans_param(my_session, task_exec_ctx, start_trans_param);
|
||||
if (OB_FAIL(ObSqlTransControl::explicit_start_trans(ctx, start_trans_param))) {
|
||||
LOG_WARN("explicit start trans failed", K(ret), K(start_trans_param));
|
||||
} else if (OB_FAIL(ps->xa_start(stmt.get_xa_string(),
|
||||
stmt.get_gtrid_string().length(),
|
||||
stmt.get_bqual_string().length(),
|
||||
stmt.get_format_id(),
|
||||
stmt.get_flags(),
|
||||
trans_desc))) {
|
||||
LOG_WARN("xa start failed", K(ret), K(start_trans_param));
|
||||
if (OB_SUCCESS != (tmp_ret = ObSqlTransControl::explicit_end_trans(ctx, true))) {
|
||||
ret = tmp_ret;
|
||||
LOG_WARN("explicit end trans failed", K(ret));
|
||||
}
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("xa start execute", K(stmt.get_xa_string()));
|
||||
return ret;
|
||||
*/
|
||||
}
|
||||
|
||||
int ObPlXaStartExecutor::execute(ObExecContext& ctx, ObXaStartStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObPhysicalPlanCtx* plan_ctx = GET_PHY_PLAN_CTX(ctx);
|
||||
ObSQLSessionInfo* my_session = GET_MY_SESSION(ctx);
|
||||
ObTaskExecutorCtx& task_exec_ctx = ctx.get_task_exec_ctx();
|
||||
storage::ObPartitionService* ps = nullptr;
|
||||
ObTransDesc& trans_desc = my_session->get_trans_desc();
|
||||
ObXATransID xid;
|
||||
|
||||
if (OB_ISNULL(plan_ctx) || OB_ISNULL(my_session) || OB_ISNULL(ps = task_exec_ctx.get_partition_service())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid param", K(ret), K(plan_ctx), K(my_session));
|
||||
ret = OB_TRANS_XA_RMFAIL;
|
||||
} else if (OB_FAIL(xid.set(stmt.get_gtrid_string(), stmt.get_bqual_string(), stmt.get_format_id()))) {
|
||||
LOG_WARN("set xid error", K(ret), K(stmt));
|
||||
} else if (my_session->get_in_transaction()) {
|
||||
ret = OB_TRANS_XA_OUTSIDE;
|
||||
LOG_WARN("already start trans", K(ret), K(stmt.get_xa_string()));
|
||||
} else {
|
||||
transaction::ObStartTransParam& start_trans_param = plan_ctx->get_start_trans_param();
|
||||
init_start_trans_param(my_session, task_exec_ctx, start_trans_param);
|
||||
|
||||
if (OB_FAIL(ObSqlTransControl::explicit_start_trans(ctx, start_trans_param))) {
|
||||
LOG_WARN("explicit start trans failed", K(ret), K(start_trans_param));
|
||||
} else if (OB_FAIL(ps->xa_start(xid, stmt.get_flags(), my_session->get_xa_end_timeout_seconds(), trans_desc))) {
|
||||
LOG_WARN("xa start failed", K(ret), K(start_trans_param));
|
||||
// if (OB_SUCCESS != (tmp_ret = ObSqlTransControl::explicit_end_trans(ctx, true))) {
|
||||
// ret = tmp_ret;
|
||||
// LOG_WARN("explicit end trans failed", K(ret));
|
||||
//}
|
||||
my_session->reset_first_stmt_type();
|
||||
my_session->reset_tx_variable();
|
||||
my_session->set_early_lock_release(false);
|
||||
ctx.set_need_disconnect(false);
|
||||
my_session->get_trans_desc().get_standalone_stmt_desc().reset();
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("xa start execute", K(stmt));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObXaEndExecutor::execute(ObExecContext& ctx, ObXaEndStmt& stmt)
|
||||
{
|
||||
int ret = OB_NOT_SUPPORTED;
|
||||
UNUSED(ctx);
|
||||
UNUSED(stmt);
|
||||
return ret;
|
||||
/*
|
||||
int ret = OB_SUCCESS;
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo *my_session = GET_MY_SESSION(ctx);
|
||||
ObTaskExecutorCtx &task_exec_ctx = ctx.get_task_exec_ctx();
|
||||
storage::ObPartitionService *ps = nullptr;
|
||||
|
||||
if (OB_ISNULL(my_session) || OB_ISNULL(ps = task_exec_ctx.get_partition_service())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid param", K(ret), K(my_session));
|
||||
} else if (OB_FAIL(ps->xa_end(stmt.get_xa_string(),
|
||||
transaction::ObXAEndFlag::TMSUCCESS,
|
||||
my_session->get_trans_desc()))) {
|
||||
LOG_WARN("xa end failed", K(ret), K(stmt.get_xa_string()));
|
||||
if (OB_TRANS_XA_RMFAIL != ret
|
||||
&& OB_SUCCESS != (tmp_ret = ObSqlTransControl::explicit_end_trans(ctx, true))) {
|
||||
ret = tmp_ret;
|
||||
LOG_WARN("explicit end trans failed", K(ret));
|
||||
}
|
||||
} else {
|
||||
my_session->reset_first_stmt_type();
|
||||
my_session->reset_tx_variable();
|
||||
my_session->set_early_lock_release(false);
|
||||
ctx.set_need_disconnect(false);
|
||||
my_session->get_trans_desc().get_standalone_stmt_desc().reset();
|
||||
}
|
||||
LOG_DEBUG("xa end execute", K(stmt.get_xa_string()));
|
||||
return ret;
|
||||
*/
|
||||
}
|
||||
|
||||
int ObPlXaEndExecutor::execute(ObExecContext& ctx, ObXaEndStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
// int tmp_ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* my_session = GET_MY_SESSION(ctx);
|
||||
ObTaskExecutorCtx& task_exec_ctx = ctx.get_task_exec_ctx();
|
||||
storage::ObPartitionService* ps = nullptr;
|
||||
ObXATransID xid;
|
||||
|
||||
if (OB_ISNULL(my_session) || OB_ISNULL(ps = task_exec_ctx.get_partition_service())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid param", K(ret), K(my_session));
|
||||
} else if (OB_FAIL(xid.set(stmt.get_gtrid_string(), stmt.get_bqual_string(), stmt.get_format_id()))) {
|
||||
LOG_WARN("set xid error", K(ret), K(stmt));
|
||||
} else if (!my_session->get_in_transaction()) {
|
||||
ret = OB_TRANS_XA_PROTO;
|
||||
LOG_WARN("not in a trans", K(ret));
|
||||
} else if (OB_FAIL(ps->xa_end(xid, stmt.get_flags(), my_session->get_trans_desc()))) {
|
||||
LOG_WARN("xa end failed", K(ret), K(stmt.get_xa_string()));
|
||||
// if (OB_TRANS_XA_RMFAIL != ret
|
||||
// && OB_SUCCESS != (tmp_ret = ObSqlTransControl::explicit_end_trans(ctx, true))) {
|
||||
// ret = tmp_ret;
|
||||
// LOG_WARN("explicit end trans failed", K(ret));
|
||||
// }
|
||||
} else {
|
||||
my_session->reset_first_stmt_type();
|
||||
my_session->reset_tx_variable();
|
||||
my_session->set_early_lock_release(false);
|
||||
ctx.set_need_disconnect(false);
|
||||
my_session->get_trans_desc().get_standalone_stmt_desc().reset();
|
||||
}
|
||||
LOG_DEBUG("xa end execute", K(stmt));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObXaPrepareExecutor::execute(ObExecContext& ctx, ObXaPrepareStmt& stmt)
|
||||
{
|
||||
int ret = OB_NOT_SUPPORTED;
|
||||
UNUSED(ctx);
|
||||
UNUSED(stmt);
|
||||
return ret;
|
||||
/*
|
||||
int ret = OB_SUCCESS;
|
||||
//int tmp_ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo *my_session = GET_MY_SESSION(ctx);
|
||||
ObTaskExecutorCtx &task_exec_ctx = ctx.get_task_exec_ctx();
|
||||
ObPhysicalPlanCtx *plan_ctx = GET_PHY_PLAN_CTX(ctx);
|
||||
storage::ObPartitionService *ps = nullptr;
|
||||
if (OB_ISNULL(my_session) || OB_ISNULL(plan_ctx)
|
||||
|| OB_ISNULL(ps = task_exec_ctx.get_partition_service())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid param", K(ret), K(my_session), K(plan_ctx), K(ps));
|
||||
} else if (my_session->get_in_transaction()) {
|
||||
ret = OB_TRANS_XA_OUTSIDE;
|
||||
LOG_WARN("already start trans", K(ret));
|
||||
} else {
|
||||
const uint64_t tenant_id = my_session->get_effective_tenant_id();
|
||||
int64_t timeout = plan_ctx->get_trans_timeout_timestamp();
|
||||
transaction::ObStartTransParam &start_trans_param = plan_ctx->get_start_trans_param();
|
||||
init_start_trans_param(my_session, task_exec_ctx, start_trans_param);
|
||||
if (OB_FAIL(ps->xa_prepare(stmt.get_xa_string(), tenant_id, timeout))) {
|
||||
LOG_WARN("xa prepare failed", K(ret), K(stmt.get_xa_string()));
|
||||
// if (OB_TRANS_XA_RMFAIL != ret
|
||||
// && OB_SUCCESS != (tmp_ret = ObSqlTransControl::explicit_end_trans(ctx, true))) {
|
||||
// ret = tmp_ret;
|
||||
// LOG_WARN("explicit end trans failed", K(ret));
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("xa prepare execute", K(stmt.get_xa_string()));
|
||||
return ret;
|
||||
*/
|
||||
}
|
||||
|
||||
int ObPlXaPrepareExecutor::execute(ObExecContext& ctx, ObXaPrepareStmt& stmt)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* my_session = GET_MY_SESSION(ctx);
|
||||
ObTaskExecutorCtx& task_exec_ctx = ctx.get_task_exec_ctx();
|
||||
ObPhysicalPlanCtx* plan_ctx = GET_PHY_PLAN_CTX(ctx);
|
||||
storage::ObPartitionService* ps = nullptr;
|
||||
ObXATransID xid;
|
||||
if (OB_ISNULL(my_session) || OB_ISNULL(plan_ctx) || OB_ISNULL(ps = task_exec_ctx.get_partition_service())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid param", K(ret), K(my_session), K(plan_ctx), K(ps));
|
||||
} else if (OB_FAIL(xid.set(stmt.get_gtrid_string(), stmt.get_bqual_string(), stmt.get_format_id()))) {
|
||||
LOG_WARN("set xid error", K(ret), K(stmt));
|
||||
} else if (my_session->get_in_transaction()) {
|
||||
ret = OB_TRANS_XA_RMERR;
|
||||
LOG_WARN("already start trans", K(ret));
|
||||
} else {
|
||||
const uint64_t tenant_id = my_session->get_effective_tenant_id();
|
||||
int64_t timeout = plan_ctx->get_trans_timeout_timestamp();
|
||||
transaction::ObStartTransParam& start_trans_param = plan_ctx->get_start_trans_param();
|
||||
init_start_trans_param(my_session, task_exec_ctx, start_trans_param);
|
||||
if (OB_FAIL(ps->xa_prepare(xid, tenant_id, timeout))) {
|
||||
if (OB_TRANS_XA_RDONLY != ret) {
|
||||
LOG_WARN("xa prepare failed", K(ret), K(stmt));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG_DEBUG("xa prepare execute", K(stmt));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObXaEndTransExecutor::execute_(const ObString& xid, const bool is_rollback, ObExecContext& ctx)
|
||||
{
|
||||
int ret = OB_NOT_SUPPORTED;
|
||||
UNUSED(xid);
|
||||
UNUSED(is_rollback);
|
||||
UNUSED(ctx);
|
||||
return ret;
|
||||
/*
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo *my_session = GET_MY_SESSION(ctx);
|
||||
ObTaskExecutorCtx &task_exec_ctx = ctx.get_task_exec_ctx();
|
||||
ObPhysicalPlanCtx *plan_ctx = GET_PHY_PLAN_CTX(ctx);
|
||||
ObTransDesc &trans_desc = my_session->get_trans_desc();
|
||||
storage::ObPartitionService *ps = nullptr;
|
||||
|
||||
if (OB_ISNULL(plan_ctx) || OB_ISNULL(my_session)
|
||||
|| OB_ISNULL(ps = task_exec_ctx.get_partition_service())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid param", K(ret), K(plan_ctx), K(my_session));
|
||||
} else if (my_session->get_in_transaction()) {
|
||||
ret = OB_TRANS_XA_OUTSIDE;
|
||||
LOG_WARN("already start trans", K(ret));
|
||||
} else {
|
||||
transaction::ObStartTransParam &start_trans_param = plan_ctx->get_start_trans_param();
|
||||
init_start_trans_param(my_session, task_exec_ctx, start_trans_param);
|
||||
if (OB_FAIL(ObSqlTransControl::explicit_start_trans(ctx, start_trans_param))) {
|
||||
LOG_WARN("explicit start trans failed", K(ret), K(start_trans_param));
|
||||
} else if (OB_FAIL(ps->xa_end_trans(xid, is_rollback, 0, trans_desc))) {
|
||||
LOG_WARN("fail to execute xa commit/rollback", K(xid), K(is_rollback));
|
||||
} else {
|
||||
LOG_DEBUG("succeed to execute xa commit/rollback", K(xid), K(is_rollback));
|
||||
}
|
||||
my_session->reset_first_stmt_type();
|
||||
my_session->reset_tx_variable();
|
||||
my_session->set_early_lock_release(false);
|
||||
ctx.set_need_disconnect(false);
|
||||
my_session->get_trans_desc().get_standalone_stmt_desc().reset();
|
||||
}
|
||||
LOG_DEBUG("xa end_trans execute", K(xid), K(is_rollback));
|
||||
return ret;
|
||||
*/
|
||||
}
|
||||
|
||||
int ObPlXaEndTransExecutor::execute_(const ObString& gtrid_str, const ObString& bqual_str, const int64_t format_id,
|
||||
const bool is_rollback, const int64_t flags, ObExecContext& ctx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo* my_session = GET_MY_SESSION(ctx);
|
||||
ObTaskExecutorCtx& task_exec_ctx = ctx.get_task_exec_ctx();
|
||||
ObPhysicalPlanCtx* plan_ctx = GET_PHY_PLAN_CTX(ctx);
|
||||
ObTransDesc& trans_desc = my_session->get_trans_desc();
|
||||
storage::ObPartitionService* ps = nullptr;
|
||||
ObXATransID xid;
|
||||
|
||||
if (OB_ISNULL(plan_ctx) || OB_ISNULL(my_session) || OB_ISNULL(ps = task_exec_ctx.get_partition_service())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid param", K(ret), K(plan_ctx), K(my_session));
|
||||
} else if (OB_FAIL(xid.set(gtrid_str, bqual_str, format_id))) {
|
||||
LOG_WARN("set xid error", K(ret), K(gtrid_str), K(bqual_str), K(format_id));
|
||||
} else if (my_session->get_in_transaction()) {
|
||||
ret = OB_TRANS_XA_RMFAIL;
|
||||
LOG_WARN("already start trans", K(ret));
|
||||
} else {
|
||||
transaction::ObStartTransParam& start_trans_param = plan_ctx->get_start_trans_param();
|
||||
init_start_trans_param(my_session, task_exec_ctx, start_trans_param);
|
||||
if (OB_FAIL(ObSqlTransControl::explicit_start_trans(ctx, start_trans_param))) {
|
||||
LOG_WARN("explicit start trans failed", K(ret), K(start_trans_param));
|
||||
} else if (OB_FAIL(ps->xa_end_trans(xid, is_rollback, flags, trans_desc))) {
|
||||
LOG_WARN("fail to execute xa commit/rollback", K(xid), K(is_rollback));
|
||||
} else {
|
||||
LOG_DEBUG("succeed to execute xa commit/rollback", K(xid), K(is_rollback));
|
||||
}
|
||||
my_session->reset_first_stmt_type();
|
||||
my_session->reset_tx_variable();
|
||||
my_session->set_early_lock_release(false);
|
||||
ctx.set_need_disconnect(false);
|
||||
my_session->get_trans_desc().get_standalone_stmt_desc().reset();
|
||||
}
|
||||
LOG_DEBUG("xa end_trans execute", K(gtrid_str), K(bqual_str), K(format_id), K(is_rollback), K(flags));
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
146
src/sql/engine/cmd/ob_xa_executor.h
Normal file
146
src/sql/engine/cmd/ob_xa_executor.h
Normal file
@ -0,0 +1,146 @@
|
||||
/**
|
||||
* Copyright (c) 2021 OceanBase
|
||||
* OceanBase CE is licensed under Mulan PubL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PubL v2.
|
||||
* You may obtain a copy of Mulan PubL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPubL-2.0
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PubL v2 for more details.
|
||||
*/
|
||||
|
||||
#ifndef OCEANBASE_SQL_ENGINE_CMD_OB_XA_CMD_EXECUTOR_
|
||||
#define OCEANBASE_SQL_ENGINE_CMD_OB_XA_CMD_EXECUTOR_
|
||||
|
||||
#include "lib/utility/ob_macro_utils.h"
|
||||
#include "lib/string/ob_string.h"
|
||||
#include "sql/resolver/xa/ob_xa_stmt.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace sql {
|
||||
class ObExecContext;
|
||||
class ObXaStartStmt;
|
||||
class ObXaStartExecutor {
|
||||
public:
|
||||
ObXaStartExecutor()
|
||||
{}
|
||||
~ObXaStartExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObXaStartStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObXaStartExecutor);
|
||||
};
|
||||
|
||||
class ObPlXaStartExecutor {
|
||||
public:
|
||||
ObPlXaStartExecutor()
|
||||
{}
|
||||
~ObPlXaStartExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObXaStartStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObPlXaStartExecutor);
|
||||
};
|
||||
|
||||
class ObXaEndStmt;
|
||||
class ObXaEndExecutor {
|
||||
public:
|
||||
ObXaEndExecutor()
|
||||
{}
|
||||
~ObXaEndExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObXaEndStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObXaEndExecutor);
|
||||
};
|
||||
|
||||
class ObPlXaEndExecutor {
|
||||
public:
|
||||
ObPlXaEndExecutor()
|
||||
{}
|
||||
~ObPlXaEndExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObXaEndStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObPlXaEndExecutor);
|
||||
};
|
||||
|
||||
class ObXaPrepareStmt;
|
||||
class ObXaPrepareExecutor {
|
||||
public:
|
||||
ObXaPrepareExecutor()
|
||||
{}
|
||||
~ObXaPrepareExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObXaPrepareStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObXaPrepareExecutor);
|
||||
};
|
||||
|
||||
class ObPlXaPrepareExecutor {
|
||||
public:
|
||||
ObPlXaPrepareExecutor()
|
||||
{}
|
||||
~ObPlXaPrepareExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObXaPrepareStmt& stmt);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObPlXaPrepareExecutor);
|
||||
};
|
||||
|
||||
class ObXaCommitStmt;
|
||||
class ObXaRollBackStmt;
|
||||
class ObXaEndTransExecutor {
|
||||
public:
|
||||
ObXaEndTransExecutor()
|
||||
{}
|
||||
~ObXaEndTransExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObXaCommitStmt& stmt)
|
||||
{
|
||||
return execute_(stmt.get_xa_string(), false, ctx);
|
||||
}
|
||||
int execute(ObExecContext& ctx, ObXaRollBackStmt& stmt)
|
||||
{
|
||||
return execute_(stmt.get_xa_string(), true, ctx);
|
||||
}
|
||||
|
||||
private:
|
||||
int execute_(const common::ObString& xid, const bool is_rollback, ObExecContext& ctx);
|
||||
DISALLOW_COPY_AND_ASSIGN(ObXaEndTransExecutor);
|
||||
};
|
||||
|
||||
class ObPlXaEndTransExecutor {
|
||||
public:
|
||||
ObPlXaEndTransExecutor()
|
||||
{}
|
||||
~ObPlXaEndTransExecutor()
|
||||
{}
|
||||
int execute(ObExecContext& ctx, ObXaCommitStmt& stmt)
|
||||
{
|
||||
return execute_(
|
||||
stmt.get_gtrid_string(), stmt.get_bqual_string(), stmt.get_format_id(), false, stmt.get_flags(), ctx);
|
||||
}
|
||||
int execute(ObExecContext& ctx, ObXaRollBackStmt& stmt)
|
||||
{
|
||||
return execute_(
|
||||
stmt.get_gtrid_string(), stmt.get_bqual_string(), stmt.get_format_id(), true, stmt.get_flags(), ctx);
|
||||
}
|
||||
|
||||
private:
|
||||
int execute_(const common::ObString& gtrid_str, const common::ObString& bqual_str, const int64_t format_id,
|
||||
const bool is_rollback, const int64_t flags, ObExecContext& ctx);
|
||||
DISALLOW_COPY_AND_ASSIGN(ObPlXaEndTransExecutor);
|
||||
};
|
||||
|
||||
} // end namespace sql
|
||||
} // end namespace oceanbase
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user