[FEAT MERGE]

Co-authored-by: leftgeek <1094669802@qq.com>
Co-authored-by: coolfishchen <coolfishchen@gmail.com>
Co-authored-by: hy-guo <fqboyg@gmail.com>
This commit is contained in:
chimyue 2024-04-19 06:46:36 +00:00 committed by ob-robot
parent 686b0aba5d
commit bf604885f8
143 changed files with 6932 additions and 1286 deletions

View File

@ -18,6 +18,7 @@
#include "lib/mysqlclient/ob_isql_connection_pool.h"
#include "lib/mysqlclient/ob_mysql_proxy.h"
#include "common/sql_mode/ob_sql_mode_utils.h"
#include "lib/mysqlclient/ob_dblink_error_trans.h"
#ifdef OB_BUILD_DBLINK
#include "lib/oracleclient/ob_oci_environment.h"
#endif

View File

@ -37,8 +37,11 @@ struct ObSessionDDLInfo final
{
public:
ObSessionDDLInfo()
: ddl_info_(0)
{}
: is_ddl_(false), is_source_table_hidden_(false), is_dest_table_hidden_(false), is_heap_table_ddl_(false),
is_ddl_check_default_value_bit_(false), is_mview_complete_refresh_(false), is_refreshing_mview_(false),
is_retryable_ddl_(false), reserved_bit_(0)
{
}
~ObSessionDDLInfo() = default;
void set_is_ddl(const bool is_ddl) { is_ddl_ = is_ddl; }
bool is_ddl() const { return is_ddl_; }
@ -78,7 +81,7 @@ public:
uint64_t is_mview_complete_refresh_: IS_MVIEW_COMPLETE_REFRESH_BIT;
uint64_t is_refreshing_mview_: IS_REFRESHING_MVIEW_BIT;
uint64_t is_retryable_ddl_: IS_RETRYABLE_DDL_BIT;
uint64_t reserved_bit : RESERVED_BIT;
uint64_t reserved_bit_ : RESERVED_BIT;
};
};
};

View File

@ -300,6 +300,10 @@ public:
v.retry_type_ = RETRY_TYPE_NONE;
}
v.no_more_test_ = true;
} else if (v.session_.get_ddl_info().is_retryable_ddl()) {
v.client_ret_ = err;
v.retry_type_ = RETRY_TYPE_NONE;
v.no_more_test_ = true;
} else if (is_load_local(v)) {
v.client_ret_ = err;
v.retry_type_ = RETRY_TYPE_NONE;

View File

@ -34,7 +34,7 @@ int ObDirectLoadControlPreBeginExecutor::deserialize()
int ObDirectLoadControlPreBeginExecutor::check_args()
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(OB_INVALID_ID == arg_.table_id_ || 0 == arg_.task_id_)) {
if (OB_UNLIKELY(OB_INVALID_ID == arg_.table_id_ || 0 == arg_.ddl_param_.task_id_)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid args", KR(ret), K(arg_));
}
@ -65,15 +65,9 @@ int ObDirectLoadControlPreBeginExecutor::process()
param.avail_memory_ = arg_.avail_memory_;
param.write_session_count_ = arg_.write_session_count_;
param.exe_mode_ = arg_.exe_mode_;
ObTableLoadDDLParam ddl_param;
uint64_t data_version = 0;
ddl_param.dest_table_id_ = arg_.dest_table_id_;
ddl_param.task_id_ = arg_.task_id_;
ddl_param.schema_version_ = arg_.schema_version_;
ddl_param.snapshot_version_ = arg_.snapshot_version_;
ddl_param.data_version_ = arg_.data_version_;
ddl_param.cluster_version_ = arg_.cluster_version_;
if (OB_FAIL(create_table_ctx(param, ddl_param, table_ctx))) {
param.method_ = arg_.method_;
param.insert_mode_ = arg_.insert_mode_;
if (OB_FAIL(create_table_ctx(param, arg_.ddl_param_, table_ctx))) {
LOG_WARN("fail to create table ctx", KR(ret));
}
if (OB_SUCC(ret)) {

View File

@ -60,16 +60,12 @@ ObDirectLoadControlPreBeginArg::ObDirectLoadControlPreBeginArg()
dup_action_(ObLoadDupActionType::LOAD_INVALID_MODE),
px_mode_(false),
online_opt_stat_gather_(false),
dest_table_id_(common::OB_INVALID_ID),
task_id_(0),
schema_version_(0),
snapshot_version_(0),
data_version_(0),
session_info_(nullptr),
avail_memory_(0),
write_session_count_(0),
exe_mode_(ObTableLoadExeMode::MAX_TYPE),
cluster_version_(0)
method_(ObDirectLoadMethod::INVALID_METHOD),
insert_mode_(ObDirectLoadInsertMode::INVALID_INSERT_MODE)
{
free_session_ctx_.sessid_ = ObSQLSessionInfo::INVALID_SESSID;
}
@ -84,7 +80,7 @@ ObDirectLoadControlPreBeginArg::~ObDirectLoadControlPreBeginArg()
}
}
OB_DEF_SERIALIZE_SIMPLE(ObDirectLoadControlPreBeginArg)
OB_DEF_SERIALIZE(ObDirectLoadControlPreBeginArg)
{
int ret = OB_SUCCESS;
LST_DO_CODE(OB_UNIS_ENCODE,
@ -94,11 +90,7 @@ OB_DEF_SERIALIZE_SIMPLE(ObDirectLoadControlPreBeginArg)
dup_action_,
px_mode_,
online_opt_stat_gather_,
dest_table_id_,
task_id_,
schema_version_,
snapshot_version_,
data_version_,
ddl_param_,
partition_id_array_,
target_partition_id_array_);
if (OB_SUCC(ret)) {
@ -109,18 +101,16 @@ OB_DEF_SERIALIZE_SIMPLE(ObDirectLoadControlPreBeginArg)
OB_UNIS_ENCODE(*session_info_);
}
}
if (OB_SUCC(ret)) {
LST_DO_CODE(OB_UNIS_ENCODE,
avail_memory_,
write_session_count_,
exe_mode_,
cluster_version_);
}
LST_DO_CODE(OB_UNIS_ENCODE,
avail_memory_,
write_session_count_,
exe_mode_,
method_,
insert_mode_);
return ret;
}
OB_DEF_DESERIALIZE_SIMPLE(ObDirectLoadControlPreBeginArg)
OB_DEF_DESERIALIZE(ObDirectLoadControlPreBeginArg)
{
int ret = OB_SUCCESS;
LST_DO_CODE(OB_UNIS_DECODE,
@ -130,11 +120,7 @@ OB_DEF_DESERIALIZE_SIMPLE(ObDirectLoadControlPreBeginArg)
dup_action_,
px_mode_,
online_opt_stat_gather_,
dest_table_id_,
task_id_,
schema_version_,
snapshot_version_,
data_version_,
ddl_param_,
partition_id_array_,
target_partition_id_array_);
if (OB_SUCC(ret)) {
@ -144,18 +130,16 @@ OB_DEF_DESERIALIZE_SIMPLE(ObDirectLoadControlPreBeginArg)
OB_UNIS_DECODE(*session_info_);
}
}
if (OB_SUCC(ret)) {
LST_DO_CODE(OB_UNIS_DECODE,
avail_memory_,
write_session_count_,
exe_mode_,
cluster_version_);
}
LST_DO_CODE(OB_UNIS_DECODE,
avail_memory_,
write_session_count_,
exe_mode_,
method_,
insert_mode_);
return ret;
}
OB_DEF_SERIALIZE_SIZE_SIMPLE(ObDirectLoadControlPreBeginArg)
OB_DEF_SERIALIZE_SIZE(ObDirectLoadControlPreBeginArg)
{
int ret = OB_SUCCESS;
int64_t len = 0;
@ -166,11 +150,7 @@ OB_DEF_SERIALIZE_SIZE_SIMPLE(ObDirectLoadControlPreBeginArg)
dup_action_,
px_mode_,
online_opt_stat_gather_,
dest_table_id_,
task_id_,
schema_version_,
snapshot_version_,
data_version_,
ddl_param_,
partition_id_array_,
target_partition_id_array_);
if (OB_SUCC(ret)) {
@ -181,112 +161,110 @@ OB_DEF_SERIALIZE_SIZE_SIMPLE(ObDirectLoadControlPreBeginArg)
OB_UNIS_ADD_LEN(*session_info_);
}
}
if (OB_SUCC(ret)) {
LST_DO_CODE(OB_UNIS_ADD_LEN,
avail_memory_,
write_session_count_,
exe_mode_,
cluster_version_);
}
LST_DO_CODE(OB_UNIS_ADD_LEN,
avail_memory_,
write_session_count_,
exe_mode_,
method_,
insert_mode_);
return len;
}
// confirm_begin
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlConfirmBeginArg,
table_id_,
task_id_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlConfirmBeginArg,
table_id_,
task_id_);
// pre_merge
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlPreMergeArg,
table_id_,
task_id_,
committed_trans_id_array_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlPreMergeArg,
table_id_,
task_id_,
committed_trans_id_array_);
// start_merge
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlStartMergeArg,
table_id_,
task_id_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlStartMergeArg,
table_id_,
task_id_);
// commit
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlCommitArg,
table_id_,
task_id_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlCommitArg,
table_id_,
task_id_);
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlCommitRes,
result_info_,
sql_statistics_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlCommitRes,
result_info_,
sql_statistics_);
// abort
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlAbortArg,
table_id_,
task_id_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlAbortArg,
table_id_,
task_id_);
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlAbortRes,
is_stopped_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlAbortRes,
is_stopped_);
// get_status
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlGetStatusArg,
table_id_,
task_id_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlGetStatusArg,
table_id_,
task_id_);
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlGetStatusRes,
status_,
error_code_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlGetStatusRes,
status_,
error_code_);
// heartbeat
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlHeartBeatArg,
table_id_,
task_id_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlHeartBeatArg,
table_id_,
task_id_);
// pre_start_trans
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlPreStartTransArg,
table_id_,
task_id_,
trans_id_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlPreStartTransArg,
table_id_,
task_id_,
trans_id_);
// confirm_start_trans
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlConfirmStartTransArg,
table_id_,
task_id_,
trans_id_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlConfirmStartTransArg,
table_id_,
task_id_,
trans_id_);
// pre_finish_trans
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlPreFinishTransArg,
table_id_,
task_id_,
trans_id_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlPreFinishTransArg,
table_id_,
task_id_,
trans_id_);
// confirm_finish_trans
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlConfirmFinishTransArg,
table_id_,
task_id_,
trans_id_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlConfirmFinishTransArg,
table_id_,
task_id_,
trans_id_);
// abandon_trans
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlAbandonTransArg,
table_id_,
task_id_,
trans_id_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlAbandonTransArg,
table_id_,
task_id_,
trans_id_);
// get_trans_status
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlGetTransStatusArg,
table_id_,
task_id_,
trans_id_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlGetTransStatusArg,
table_id_,
task_id_,
trans_id_);
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlGetTransStatusRes,
trans_status_,
error_code_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlGetTransStatusRes,
trans_status_,
error_code_);
// insert_trans
OB_SERIALIZE_MEMBER_SIMPLE(ObDirectLoadControlInsertTransArg,
table_id_,
task_id_,
trans_id_,
session_id_,
sequence_no_,
payload_);
OB_SERIALIZE_MEMBER(ObDirectLoadControlInsertTransArg,
table_id_,
task_id_,
trans_id_,
session_id_,
sequence_no_,
payload_);
} // namespace observer
} // namespace oceanbase

View File

@ -15,11 +15,13 @@
#include "lib/container/ob_array_serialization.h"
#include "lib/utility/ob_print_utils.h"
#include "lib/utility/ob_unify_serialize.h"
#include "observer/table_load/ob_table_load_struct.h"
#include "share/table/ob_table_load_array.h"
#include "share/table/ob_table_load_define.h"
#include "share/table/ob_table_load_sql_statistics.h"
#include "sql/session/ob_sql_session_mgr.h"
#include "observer/table_load/ob_table_load_struct.h"
#include "storage/direct_load/ob_direct_load_struct.h"
namespace oceanbase
{
@ -51,7 +53,7 @@ enum class ObDirectLoadControlCommandType
struct ObDirectLoadControlRequest
{
OB_UNIS_VERSION(1);
OB_UNIS_VERSION(2);
public:
ObDirectLoadControlRequest() : command_type_(observer::ObDirectLoadControlCommandType::MAX_TYPE)
@ -96,7 +98,7 @@ public:
class ObDirectLoadControlResult
{
OB_UNIS_VERSION(1);
OB_UNIS_VERSION(2);
public:
ObDirectLoadControlResult()
@ -152,11 +154,22 @@ class ObDirectLoadControlPreBeginArg final
public:
ObDirectLoadControlPreBeginArg();
~ObDirectLoadControlPreBeginArg();
TO_STRING_KV(K_(table_id), K_(config), K_(column_count), K_(dup_action), K_(px_mode),
K_(online_opt_stat_gather), K_(dest_table_id), K_(task_id), K_(schema_version),
K_(snapshot_version), K_(data_version), K_(partition_id_array),
K_(target_partition_id_array), K_(avail_memory), K_(write_session_count),
K_(exe_mode), K_(cluster_version));
TO_STRING_KV(K_(table_id),
K_(config),
K_(column_count),
K_(dup_action),
K_(px_mode),
K_(online_opt_stat_gather),
K_(ddl_param),
K_(partition_id_array),
K_(target_partition_id_array),
KP_(session_info),
K_(free_session_ctx),
K_(avail_memory),
K_(write_session_count),
K_(exe_mode),
"method", storage::ObDirectLoadMethod::get_type_string(method_),
"insert_mode", storage::ObDirectLoadInsertMode::get_type_string(insert_mode_));
public:
uint64_t table_id_;
@ -165,12 +178,7 @@ public:
sql::ObLoadDupActionType dup_action_;
bool px_mode_;
bool online_opt_stat_gather_;
// ddl param
uint64_t dest_table_id_;
int64_t task_id_;
int64_t schema_version_;
int64_t snapshot_version_;
int64_t data_version_;
ObTableLoadDDLParam ddl_param_;
// partition info
table::ObTableLoadArray<table::ObTableLoadLSIdAndPartitionId> partition_id_array_; // origin table
table::ObTableLoadArray<table::ObTableLoadLSIdAndPartitionId> target_partition_id_array_; // target table
@ -179,7 +187,8 @@ public:
int64_t avail_memory_;
int32_t write_session_count_;
ObTableLoadExeMode exe_mode_;
uint64_t cluster_version_;
storage::ObDirectLoadMethod::Type method_;
storage::ObDirectLoadInsertMode::Type insert_mode_;
};
class ObDirectLoadControlConfirmBeginArg final

View File

@ -589,6 +589,8 @@ int ObTableLoadClientTask::init_instance()
load_param.px_mode_ = false;
load_param.online_opt_stat_gather_ = false; // 支持统计信息收集需要构造ObExecContext
load_param.dup_action_ = param_.get_dup_action();
load_param.method_ = ObDirectLoadMethod::FULL;
load_param.insert_mode_ = ObDirectLoadInsertMode::NORMAL;
const ObTableLoadTableCtx *tmp_ctx = nullptr;
if (OB_FAIL(instance_.init(load_param, column_idxs, exec_ctx_))) {
LOG_WARN("fail to init instance", KR(ret));

View File

@ -28,6 +28,7 @@
#include "observer/table_load/ob_table_load_utils.h"
#include "share/ob_share_util.h"
#include "share/stat/ob_incremental_stat_estimator.h"
#include "observer/omt/ob_tenant.h"
namespace oceanbase
{
@ -484,15 +485,12 @@ int ObTableLoadCoordinator::pre_begin_peers(ObDirectLoadResourceApplyArg &apply_
arg.dup_action_ = param_.dup_action_;
arg.px_mode_ = param_.px_mode_;
arg.online_opt_stat_gather_ = param_.online_opt_stat_gather_;
arg.dest_table_id_ = ctx_->ddl_param_.dest_table_id_;
arg.task_id_ = ctx_->ddl_param_.task_id_;
arg.schema_version_ = ctx_->ddl_param_.schema_version_;
arg.snapshot_version_ = ctx_->ddl_param_.snapshot_version_;
arg.data_version_ = ctx_->ddl_param_.data_version_;
arg.cluster_version_ = ctx_->ddl_param_.cluster_version_;
arg.ddl_param_ = ctx_->ddl_param_;
arg.session_info_ = ctx_->session_info_;
arg.write_session_count_ = param_.write_session_count_;
arg.exe_mode_ = ctx_->param_.exe_mode_;
arg.method_ = param_.method_;
arg.insert_mode_ = param_.insert_mode_;
for (int64_t i = 0; OB_SUCC(ret) && i < all_leader_info_array.count(); ++i) {
const ObTableLoadPartitionLocation::LeaderInfo &leader_info = all_leader_info_array.at(i);
const ObTableLoadPartitionLocation::LeaderInfo &target_leader_info =

View File

@ -81,8 +81,10 @@ int ObTableLoadInstance::init(ObTableLoadParam &param, const ObIArray<int64_t> &
LOG_WARN("fail to check tenant", KR(ret), K(param.tenant_id_));
}
// check support
else if (OB_FAIL(ObTableLoadService::check_support_direct_load(param.table_id_))) {
LOG_WARN("fail to check support direct load", KR(ret), K(param.table_id_));
else if (OB_FAIL(ObTableLoadService::check_support_direct_load(param.table_id_,
param.method_,
param.insert_mode_))) {
LOG_WARN("fail to check support direct load", KR(ret), K(param));
}
// create table ctx
else if (OB_FAIL(create_table_ctx(param, idx_array))) {

View File

@ -284,6 +284,7 @@ int ObTableLoadMerger::build_merge_ctx()
merge_param.is_column_store_ = store_ctx_->ctx_->schema_.is_column_store_;
merge_param.fill_cg_thread_cnt_ = param_.session_count_;
merge_param.px_mode_ = param_.px_mode_;
merge_param.insert_mode_ = param_.insert_mode_;
merge_param.insert_table_ctx_ = store_ctx_->insert_table_ctx_;
merge_param.dml_row_handler_ = store_ctx_->error_row_handler_;
if (OB_FAIL(merge_ctx_.init(store_ctx_->ctx_, merge_param, store_ctx_->ls_partition_ids_,

View File

@ -34,6 +34,18 @@ int ObTableLoadRedefTable::start(const ObTableLoadRedefTableStartArg &arg,
if (OB_UNLIKELY(!arg.is_valid())) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid args", KR(ret), K(arg));
} else if (session_info.get_ddl_info().is_mview_complete_refresh()) {
res.task_id_ = session_info.get_cur_exec_ctx()->get_table_direct_insert_ctx().get_ddl_task_id();
share::ObDDLTaskStatus status = share::ObDDLTaskStatus::PREPARE;
if (OB_FAIL(ObDDLUtil::get_data_information(arg.tenant_id_,
res.task_id_,
res.data_format_version_,
res.snapshot_version_,
status,
res.dest_table_id_,
res.schema_version_))) {
LOG_WARN("fail to get ddl task info", KR(ret), K(arg));
}
} else {
const int64_t origin_timeout_ts = THIS_WORKER.get_timeout_ts();
ObCreateHiddenTableArg create_table_arg;
@ -78,6 +90,8 @@ int ObTableLoadRedefTable::finish(const ObTableLoadRedefTableFinishArg &arg,
if (OB_UNLIKELY(!arg.is_valid())) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid args", KR(ret), K(arg));
} else if (session_info.get_ddl_info().is_mview_complete_refresh()) {
//pass
} else {
const int64_t origin_timeout_ts = THIS_WORKER.get_timeout_ts();
ObCopyTableDependentsArg copy_table_dependents_arg;
@ -131,6 +145,8 @@ int ObTableLoadRedefTable::abort(const ObTableLoadRedefTableAbortArg &arg,
if (OB_UNLIKELY(!arg.is_valid())) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid args", KR(ret), K(arg));
} else if (session_info.get_ddl_info().is_mview_complete_refresh()) {
//pass
} else {
const int64_t origin_timeout_ts = THIS_WORKER.get_timeout_ts();
ObAbortRedefTableArg abort_redef_table_arg;

View File

@ -393,12 +393,17 @@ int ObTableLoadService::check_tenant()
return ret;
}
int ObTableLoadService::check_support_direct_load(uint64_t table_id)
int ObTableLoadService::check_support_direct_load(
const uint64_t table_id,
const ObDirectLoadMethod::Type method,
const ObDirectLoadInsertMode::Type insert_mode)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(OB_INVALID_ID == table_id)) {
if (OB_UNLIKELY(OB_INVALID_ID == table_id ||
!ObDirectLoadMethod::is_type_valid(method) ||
!ObDirectLoadInsertMode::is_type_valid(insert_mode))) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid args", KR(ret), K(table_id));
LOG_WARN("invalid args", KR(ret), K(table_id), K(method), K(insert_mode));
} else {
const uint64_t tenant_id = MTL_ID();
ObSchemaGetterGuard schema_guard;
@ -453,6 +458,15 @@ int ObTableLoadService::check_support_direct_load(uint64_t table_id)
ret = OB_NOT_SUPPORTED;
LOG_WARN("direct-load does not support table with materialized view log", KR(ret));
FORWARD_USER_ERROR_MSG(ret, "direct-load does not support table with materialized view log");
} else if (OB_UNLIKELY(ObDirectLoadMethod::is_incremental(method))) { // incremental direct-load
ret = OB_NOT_SUPPORTED;
LOG_WARN("incremental direct-load is not supported", KR(ret));
FORWARD_USER_ERROR_MSG(ret, "incremental direct-load is not supported");
} else if (ObDirectLoadMethod::is_full(method)) { // full direct-load
if (OB_UNLIKELY(!ObDirectLoadInsertMode::is_valid_for_full_method(insert_mode))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected insert mode for full direct-load", KR(ret), K(method), K(insert_mode));
}
}
}
return ret;

View File

@ -22,6 +22,7 @@
#include "observer/table_load/ob_table_load_assigned_memory_manager.h"
#include "observer/table_load/resource/ob_table_load_resource_rpc_proxy.h"
#include "observer/table_load/resource/ob_table_load_resource_service.h"
#include "storage/direct_load/ob_direct_load_struct.h"
namespace oceanbase
{
@ -34,7 +35,9 @@ class ObTableLoadService
public:
static int mtl_init(ObTableLoadService *&service);
static int check_tenant();
static int check_support_direct_load(uint64_t table_id);
static int check_support_direct_load(const uint64_t table_id,
const storage::ObDirectLoadMethod::Type method,
const storage::ObDirectLoadInsertMode::Type insert_mode);
static ObTableLoadTableCtx *alloc_ctx();
static void free_ctx(ObTableLoadTableCtx *table_ctx);
static int add_ctx(ObTableLoadTableCtx *table_ctx);

View File

@ -1,5 +1,5 @@
/**
* Copyright (c) 2023 OceanBase
* Copyright (c) 2024 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:
@ -9,12 +9,27 @@
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#define USING_LOG_PREFIX SERVER
#include "observer/table_load/ob_table_load_struct.h"
namespace oceanbase
namespace oceanbase
{
namespace observer
{
using namespace common;
using namespace table;
OB_SERIALIZE_MEMBER_SIMPLE(ObTableLoadUniqueKey, table_id_, task_id_);
OB_SERIALIZE_MEMBER(ObTableLoadDDLParam,
dest_table_id_,
task_id_,
schema_version_,
snapshot_version_,
data_version_,
cluster_version_);
} // namespace observer
} // namespace oceanbase
} // namespace oceanbase

View File

@ -17,6 +17,7 @@
#include "lib/utility/ob_print_utils.h"
#include "share/table/ob_table_load_array.h"
#include "sql/resolver/cmd/ob_load_data_stmt.h"
#include "storage/direct_load/ob_direct_load_struct.h"
namespace oceanbase
{
@ -145,7 +146,9 @@ struct ObTableLoadParam
dup_action_(sql::ObLoadDupActionType::LOAD_INVALID_MODE),
avail_memory_(0),
write_session_count_(0),
exe_mode_(ObTableLoadExeMode::MAX_TYPE)
exe_mode_(ObTableLoadExeMode::MAX_TYPE),
method_(storage::ObDirectLoadMethod::INVALID_METHOD),
insert_mode_(storage::ObDirectLoadInsertMode::INVALID_INSERT_MODE)
{
}
@ -167,12 +170,37 @@ struct ObTableLoadParam
parallel_ > 0 &&
session_count_ > 0 &&
batch_size_ > 0 &&
column_count_ > 0;
column_count_ > 0 &&
sql::ObLoadDupActionType::LOAD_INVALID_MODE != dup_action_ &&
storage::ObDirectLoadMethod::is_type_valid(method_) &&
storage::ObDirectLoadInsertMode::is_type_valid(insert_mode_) &&
(storage::ObDirectLoadMethod::is_full(method_)
? storage::ObDirectLoadInsertMode::is_valid_for_full_method(insert_mode_)
: true) &&
(storage::ObDirectLoadMethod::is_incremental(method_)
? storage::ObDirectLoadInsertMode::is_valid_for_incremental_method(insert_mode_)
: true) &&
(storage::ObDirectLoadInsertMode::INC_REPLACE == insert_mode_
? sql::ObLoadDupActionType::LOAD_REPLACE == dup_action_
: true);
}
TO_STRING_KV(K_(tenant_id), K_(table_id), K_(parallel), K_(session_count), K_(batch_size),
K_(max_error_row_count), K_(sql_mode), K_(column_count), K_(need_sort), K_(px_mode),
K_(online_opt_stat_gather), K_(dup_action), K_(avail_memory), K_(write_session_count), K_(exe_mode));
TO_STRING_KV(K_(tenant_id),
K_(table_id),
K_(parallel),
K_(session_count),
K_(batch_size),
K_(max_error_row_count),
K_(column_count),
K_(need_sort),
K_(px_mode),
K_(online_opt_stat_gather),
K_(dup_action),
K_(avail_memory),
K_(write_session_count),
K_(exe_mode),
"method", storage::ObDirectLoadMethod::get_type_string(method_),
"insert_mode", storage::ObDirectLoadInsertMode::get_type_string(insert_mode_));
public:
uint64_t tenant_id_;
uint64_t table_id_;
@ -180,7 +208,7 @@ public:
int32_t session_count_;
int32_t batch_size_;
uint64_t max_error_row_count_;
uint64_t sql_mode_;
uint64_t sql_mode_; // unused
int32_t column_count_;
bool need_sort_;
bool px_mode_;
@ -189,10 +217,13 @@ public:
int64_t avail_memory_;
int32_t write_session_count_;
ObTableLoadExeMode exe_mode_;
storage::ObDirectLoadMethod::Type method_;
storage::ObDirectLoadInsertMode::Type insert_mode_;
};
struct ObTableLoadDDLParam
{
OB_UNIS_VERSION(1);
public:
ObTableLoadDDLParam()
: dest_table_id_(common::OB_INVALID_ID),

View File

@ -191,8 +191,8 @@ int ObTableLoadTransBucketWriter::write(int32_t session_id, ObTableLoadObjRowArr
}
} else {
if (coordinator_ctx_->partition_calc_.is_partition_with_autoinc_ &&
OB_FAIL(handle_partition_with_autoinc_identity(session_ctx, obj_rows, param_.sql_mode_,
session_id))) {
OB_FAIL(handle_partition_with_autoinc_identity(session_ctx, obj_rows,
trans_ctx_->ctx_->session_info_->get_sql_mode(), session_id))) {
LOG_WARN("fail to handle partition column with autoincrement or identity", KR(ret));
} else if (OB_FAIL(write_for_partitioned(session_ctx, obj_rows))) {
LOG_WARN("fail to write for partitioned", KR(ret));

View File

@ -442,7 +442,7 @@ int ObTableLoadTransStoreWriter::handle_autoinc_column(const ObColumnSchemaV2 *c
int ret = OB_SUCCESS;
if (OB_FAIL(ObTableLoadAutoincNextval::eval_nextval(
&(store_ctx_->session_ctx_array_[session_id - 1].autoinc_param_), datum, tc,
param_.sql_mode_))) {
store_ctx_->ctx_->session_info_->get_sql_mode()))) {
LOG_WARN("fail to get auto increment next value", KR(ret));
}
return ret;

View File

@ -187,6 +187,7 @@ ob_set_subtarget(ob_rootserver mview
mview/ob_mview_maintenance_task.cpp
mview/ob_mview_refresh_stats_maintenance_task.cpp
mview/ob_mview_timer_task.cpp
mview/ob_mview_dependency_service.cpp
)
ob_server_add_target(ob_rootserver)

View File

@ -52,12 +52,13 @@ ObDDLRedefinitionSSTableBuildTask::ObDDLRedefinitionSSTableBuildTask(
const int64_t mview_table_id,
ObRootService *root_service,
const common::ObAddr &inner_sql_exec_addr,
const int64_t data_format_version)
const int64_t data_format_version,
const bool is_retryable_ddl)
: is_inited_(false), tenant_id_(tenant_id), task_id_(task_id), data_table_id_(data_table_id),
dest_table_id_(dest_table_id), schema_version_(schema_version), snapshot_version_(snapshot_version),
execution_id_(execution_id), consumer_group_id_(consumer_group_id), sql_mode_(sql_mode), trace_id_(trace_id),
parallelism_(parallelism), use_heap_table_ddl_plan_(use_heap_table_ddl_plan),
is_mview_complete_refresh_(is_mview_complete_refresh), mview_table_id_(mview_table_id),
is_mview_complete_refresh_(is_mview_complete_refresh), is_retryable_ddl_(is_retryable_ddl), mview_table_id_(mview_table_id),
root_service_(root_service), inner_sql_exec_addr_(inner_sql_exec_addr), data_format_version_(0)
{
set_retry_times(0); // do not retry
@ -130,7 +131,7 @@ int ObDDLRedefinitionSSTableBuildTask::process()
if (is_mview_complete_refresh_) {
if (OB_FAIL(ObDDLUtil::generate_build_mview_replica_sql(tenant_id_,
mview_table_id_,
dest_table_id_,
data_table_id_,
schema_guard,
snapshot_version_,
execution_id_,
@ -167,11 +168,12 @@ int ObDDLRedefinitionSSTableBuildTask::process()
ObSessionParam session_param;
session_param.sql_mode_ = reinterpret_cast<int64_t *>(&sql_mode_);
session_param.tz_info_wrap_ = &tz_info_wrap_;
session_param.ddl_info_.set_is_ddl(true);
session_param.ddl_info_.set_is_ddl(!is_mview_complete_refresh_);
session_param.ddl_info_.set_source_table_hidden(false);
session_param.ddl_info_.set_dest_table_hidden(true);
session_param.ddl_info_.set_heap_table_ddl(use_heap_table_ddl_plan_);
session_param.ddl_info_.set_mview_complete_refresh(is_mview_complete_refresh_);
session_param.ddl_info_.set_retryable_ddl(is_retryable_ddl_);
session_param.use_external_session_ = true; // means session id dispatched by session mgr
session_param.consumer_group_id_ = consumer_group_id_;
@ -200,7 +202,7 @@ int ObDDLRedefinitionSSTableBuildTask::process()
oracle_mode ? ObCompatibilityMode::ORACLE_MODE : ObCompatibilityMode::MYSQL_MODE, &session_param, sql_exec_addr))) {
LOG_WARN("fail to execute build replica sql", K(ret), K(tenant_id_));
}
if (OB_SUCC(ret)) {
if (OB_SUCC(ret) && !is_mview_complete_refresh_) {
if (OB_FAIL(ObCheckTabletDataComplementOp::check_finish_report_checksum(tenant_id_, dest_table_id_, execution_id_, task_id_))) {
LOG_WARN("fail to check sstable checksum_report_finish",
K(ret), K(tenant_id_), K(dest_table_id_), K(execution_id_), K(task_id_));
@ -257,7 +259,8 @@ ObAsyncTask *ObDDLRedefinitionSSTableBuildTask::deep_copy(char *buf, const int64
mview_table_id_,
root_service_,
inner_sql_exec_addr_,
data_format_version_);
data_format_version_,
is_retryable_ddl_);
if (OB_FAIL(new_task->tz_info_wrap_.deep_copy(tz_info_wrap_))) {
LOG_WARN("failed to copy tz info wrap", K(ret));
} else if (OB_FAIL(new_task->col_name_map_.assign(col_name_map_))) {

View File

@ -42,7 +42,8 @@ public:
const int64_t mview_table_id,
ObRootService *root_service,
const common::ObAddr &inner_sql_exec_addr,
const int64_t data_format_version = 0);
const int64_t data_format_version,
const bool is_retryable_ddl);
int init(
const ObTableSchema &orig_table_schema,
const ObTableSchema &hidden_table_schema,
@ -72,6 +73,7 @@ private:
int64_t parallelism_;
bool use_heap_table_ddl_plan_;
bool is_mview_complete_refresh_;
bool is_retryable_ddl_;
int64_t mview_table_id_;
common::ObArray<share::schema::ObBasedSchemaObjectInfo> based_schema_object_infos_;
ObRootService *root_service_;

View File

@ -1025,6 +1025,7 @@ int ObDDLScheduler::create_ddl_task(const ObCreateDDLTaskParam &param,
case DDL_DIRECT_LOAD_INSERT:
case DDL_ALTER_COLUMN_GROUP:
case DDL_MVIEW_COMPLETE_REFRESH:
case DDL_MODIFY_AUTO_INCREMENT_WITH_REDEFINITION:
if (OB_FAIL(create_table_redefinition_task(proxy,
param.type_,
param.src_table_schema_,
@ -2076,6 +2077,7 @@ int ObDDLScheduler::schedule_ddl_task(const ObDDLTaskRecord &record)
case DDL_DIRECT_LOAD_INSERT:
case DDL_ALTER_COLUMN_GROUP:
case DDL_MVIEW_COMPLETE_REFRESH:
case DDL_MODIFY_AUTO_INCREMENT_WITH_REDEFINITION:
ret = schedule_table_redefinition_task(record);
break;
case DDL_CREATE_MVIEW:
@ -2648,6 +2650,7 @@ int ObDDLScheduler::on_sstable_complement_job_reply(
case ObDDLType::DDL_TABLE_REDEFINITION:
case ObDDLType::DDL_ALTER_COLUMN_GROUP:
case ObDDLType::DDL_MVIEW_COMPLETE_REFRESH:
case ObDDLType::DDL_MODIFY_AUTO_INCREMENT_WITH_REDEFINITION:
if (OB_FAIL(static_cast<ObTableRedefinitionTask *>(&task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code, addition_info))) {
LOG_WARN("update complete sstable job status", K(ret));
}
@ -2781,6 +2784,7 @@ int ObDDLScheduler::notify_update_autoinc_end(const ObDDLTaskKey &task_key,
case ObDDLType::DDL_DIRECT_LOAD_INSERT:
case ObDDLType::DDL_ALTER_COLUMN_GROUP:
case ObDDLType::DDL_MVIEW_COMPLETE_REFRESH:
case ObDDLType::DDL_MODIFY_AUTO_INCREMENT_WITH_REDEFINITION:
if (OB_FAIL(static_cast<ObTableRedefinitionTask *>(&task)->notify_update_autoinc_finish(autoinc_val, ret_code))) {
LOG_WARN("update complete sstable job status", K(ret));
}

View File

@ -814,6 +814,9 @@ int ObDDLTask::get_ddl_type_str(const int64_t ddl_type, const char *&ddl_type_st
case DDL_MANUAL_SPLIT_NON_RANGE:
ddl_type_str = "manual split non range";
break;
case DDL_MODIFY_AUTO_INCREMENT_WITH_REDEFINITION:
ddl_type_str = "modify auto increment column with redefinition";
break;
default:
ret = OB_ERR_UNEXPECTED;
}
@ -980,6 +983,7 @@ int ObDDLTask::convert_to_record(
task_record.task_version_ = get_task_version();
task_record.execution_id_ = get_execution_id();
task_record.ret_code_ = get_ret_code();
task_record.ddl_need_retry_at_executor_ = !task_can_retry();
const ObString &ddl_stmt_str = get_ddl_stmt_str();
if (serialize_param_size > 0) {
char *buf = nullptr;
@ -1413,7 +1417,7 @@ int64_t ObDDLTask::get_execution_id() const
return execution_id_;
}
int ObDDLTask::push_execution_id(const uint64_t tenant_id, const int64_t task_id, int64_t &new_execution_id)
int ObDDLTask::push_execution_id(const uint64_t tenant_id, const int64_t task_id, const bool ddl_can_retry, const int64_t data_format_version, int64_t &new_execution_id)
{
int ret = OB_SUCCESS;
ObMySQLTransaction trans;
@ -1429,8 +1433,29 @@ int ObDDLTask::push_execution_id(const uint64_t tenant_id, const int64_t task_id
} else {
if (OB_FAIL(ObDDLTaskRecordOperator::select_for_update(trans, tenant_id, task_id, task_status, execution_id, ret_code))) {
LOG_WARN("select for update failed", K(ret), K(task_id));
} else if (OB_FAIL(ObDDLTaskRecordOperator::update_execution_id(trans, tenant_id, task_id, execution_id + 1))) {
LOG_WARN("update task status failed", K(ret));
} else {
LOG_INFO("push execution id", K(tenant_id), K(task_id), K(task_status), K(execution_id), K(ret_code));
if (ObDDLUtil::use_idempotent_mode(data_format_version)) {
if (0 == execution_id) {
// has been executed before
if (!ddl_can_retry) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("do not retry for heap table ddl plan", K(tenant_id), K(task_id), K(ddl_can_retry));
} else {
if (OB_FAIL(ObDDLTaskRecordOperator::update_execution_id(trans, tenant_id, task_id, 0L/*execution id*/))) {
LOG_WARN("update task status failed", K(ret));
} else {
new_execution_id = 0L;
}
}
}
} else {
if (OB_FAIL(ObDDLTaskRecordOperator::update_execution_id(trans, tenant_id, task_id, execution_id + 1))) {
LOG_WARN("update task status failed", K(ret));
} else {
new_execution_id = execution_id + 1;
}
}
}
bool commit = (OB_SUCCESS == ret);
int tmp_ret = trans.end(commit);
@ -1438,9 +1463,6 @@ int ObDDLTask::push_execution_id(const uint64_t tenant_id, const int64_t task_id
LOG_WARN("fail to end trans", K(tmp_ret));
ret = (OB_SUCCESS == ret) ? tmp_ret : ret;
}
if (OB_SUCC(ret)) {
new_execution_id = execution_id + 1;
}
}
return ret;
}

View File

@ -75,7 +75,8 @@ public:
bool is_valid() const;
void reset();
TO_STRING_KV(K_(task_id), K_(parent_task_id), K_(ddl_type), K_(trace_id), K_(task_status), K_(tenant_id), K_(object_id),
K_(schema_version), K_(target_object_id), K_(snapshot_version), K_(message), K_(task_version), K_(ret_code), K_(execution_id));
K_(schema_version), K_(target_object_id), K_(snapshot_version), K_(message), K_(task_version), K_(ret_code), K_(execution_id),
K_(ddl_need_retry_at_executor));
public:
static const int64_t MAX_MESSAGE_LENGTH = 4096;
typedef common::ObFixedLengthString<MAX_MESSAGE_LENGTH> TaskMessage;
@ -96,6 +97,7 @@ public:
int64_t ret_code_;
int64_t execution_id_;
ObString ddl_stmt_str_;
bool ddl_need_retry_at_executor_;
};
struct ObDDLTaskInfo final
@ -557,7 +559,12 @@ public:
bool need_schedule() { return next_schedule_ts_ <= ObTimeUtility::current_time(); }
bool is_replica_build_need_retry(const int ret_code);
int64_t get_execution_id() const;
static int push_execution_id(const uint64_t tenant_id, const int64_t task_id, int64_t &new_execution_id);
static int push_execution_id(
const uint64_t tenant_id,
const int64_t task_id,
const bool ddl_can_retry,
const int64_t data_format_version,
int64_t &new_execution_id);
void check_ddl_task_execute_too_long();
static bool check_is_load_data(share::ObDDLType task_type);
virtual bool support_longops_monitoring() const { return false; }
@ -608,10 +615,11 @@ protected:
int copy_longops_stat(share::ObLongopsValue &value);
virtual bool is_error_need_retry(const int ret_code)
{
return !share::ObIDDLTask::in_ddl_retry_black_list(ret_code) && (share::ObIDDLTask::in_ddl_retry_white_list(ret_code)
|| MAX_ERR_TOLERANCE_CNT > ++err_code_occurence_cnt_);
return task_can_retry() && (!share::ObIDDLTask::in_ddl_retry_black_list(ret_code) && (share::ObIDDLTask::in_ddl_retry_white_list(ret_code)
|| MAX_ERR_TOLERANCE_CNT > ++err_code_occurence_cnt_));
}
int init_ddl_task_monitor_info(const uint64_t target_table_id);
virtual bool task_can_retry() const { return true; }
protected:
static const int64_t TASK_EXECUTE_TIME_THRESHOLD = 3 * 24 * 60 * 60 * 1000000L; // 3 days
common::TCRWLock lock_;

View File

@ -853,7 +853,7 @@ int ObIndexBuildTask::send_build_single_replica_request()
LOG_WARN("ObIndexBuildTask has not been inited", K(ret));
} else if (OB_FAIL(DDL_SIM(tenant_id_, task_id_, DDL_TASK_SEND_BUILD_REPLICA_REQUEST_FAILED))) {
LOG_WARN("ddl sim failure", K(ret), K(tenant_id_), K(task_id_));
} else if (OB_FAIL(ObDDLTask::push_execution_id(tenant_id_, task_id_, new_execution_id))) {
} else if (OB_FAIL(ObDDLTask::push_execution_id(tenant_id_, task_id_, true/*is ddl retryable*/, data_format_version_, new_execution_id))) {
LOG_WARN("failed to fetch new execution id", K(ret));
} else {
if (OB_FAIL(ObDDLUtil::get_sys_ls_leader_addr(GCONF.cluster_id, tenant_id_, create_index_arg_.inner_sql_exec_addr_))) {

View File

@ -39,7 +39,8 @@ ObTableRedefinitionTask::ObTableRedefinitionTask()
has_rebuild_index_(false), has_rebuild_constraint_(false), has_rebuild_foreign_key_(false),
allocator_(lib::ObLabel("RedefTask")),
is_copy_indexes_(true), is_copy_triggers_(true), is_copy_constraints_(true), is_copy_foreign_keys_(true),
is_ignore_errors_(false), is_do_finish_(false), target_cg_cnt_(0)
is_ignore_errors_(false), is_do_finish_(false), target_cg_cnt_(0), use_heap_table_ddl_plan_(false),
is_ddl_retryable_(true)
{
}
@ -114,6 +115,8 @@ int ObTableRedefinitionTask::init(const ObTableSchema* src_table_schema,
LOG_WARN("fail to get target cg cnt", K(ret), KPC(dst_table_schema));
} else if (OB_FAIL(init_ddl_task_monitor_info(target_object_id_))) {
LOG_WARN("init ddl task monitor info failed", K(ret));
} else if (OB_FAIL(check_ddl_can_retry(dst_table_schema))) {
LOG_WARN("check use heap table ddl plan failed", K(ret));
} else {
is_inited_ = true;
ddl_tracing_.open();
@ -259,7 +262,6 @@ int ObTableRedefinitionTask::send_build_replica_request_by_sql()
{
int ret = OB_SUCCESS;
bool modify_autoinc = false;
bool use_heap_table_ddl_plan = false;
ObRootService *root_service = GCTX.root_service_;
int64_t new_execution_id = 0;
if (OB_ISNULL(root_service)) {
@ -269,9 +271,7 @@ int ObTableRedefinitionTask::send_build_replica_request_by_sql()
LOG_WARN("ddl sim failure", K(tenant_id_), K(task_id_));
} else if (OB_FAIL(check_modify_autoinc(modify_autoinc))) {
LOG_WARN("failed to check modify autoinc", K(ret));
} else if (OB_FAIL(check_use_heap_table_ddl_plan(use_heap_table_ddl_plan))) {
LOG_WARN("fail to check heap table ddl plan", K(ret));
} else if (OB_FAIL(ObDDLTask::push_execution_id(tenant_id_, task_id_, new_execution_id))) {
} else if (OB_FAIL(ObDDLTask::push_execution_id(tenant_id_, task_id_, is_ddl_retryable_, data_format_version_, new_execution_id))) {
LOG_WARN("failed to fetch new execution id", K(ret));
} else {
ObSQLMode sql_mode = alter_table_arg_.sql_mode_;
@ -300,12 +300,13 @@ int ObTableRedefinitionTask::send_build_replica_request_by_sql()
sql_mode,
trace_id_,
parallelism_,
use_heap_table_ddl_plan,
use_heap_table_ddl_plan_,
alter_table_arg_.mview_refresh_info_.is_mview_complete_refresh_,
alter_table_arg_.mview_refresh_info_.mview_table_id_,
GCTX.root_service_,
alter_table_arg_.inner_sql_exec_addr_,
data_format_version_);
data_format_version_,
is_ddl_retryable_);
if (OB_FAIL(root_service->get_ddl_service().get_tenant_schema_guard_with_version_in_inner_table(tenant_id_, schema_guard))) {
LOG_WARN("get schema guard failed", K(ret));
} else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, object_id_, orig_table_schema))) {
@ -331,7 +332,7 @@ int ObTableRedefinitionTask::check_build_replica_end(bool &is_end)
ret_code_ = complete_sstable_job_ret_code_;
is_end = true;
LOG_WARN("complete sstable job failed", K(ret_code_), K(object_id_), K(target_object_id_));
if (is_replica_build_need_retry(ret_code_)) {
if (is_replica_build_need_retry(ret_code_) && is_ddl_retryable_) {
build_replica_request_time_ = 0;
complete_sstable_job_ret_code_ = INT64_MAX;
ret_code_ = OB_SUCCESS;
@ -345,30 +346,42 @@ int ObTableRedefinitionTask::check_build_replica_end(bool &is_end)
return ret;
}
int ObTableRedefinitionTask::check_use_heap_table_ddl_plan(bool &use_heap_table_ddl_plan)
int ObTableRedefinitionTask::check_ddl_can_retry(const ObTableSchema *table_schema)
{
int ret = OB_SUCCESS;
use_heap_table_ddl_plan = false;
ObSchemaGetterGuard schema_guard;
const ObTableSchema *target_table_schema = nullptr;
ObRootService *root_service = GCTX.root_service_;
if (OB_ISNULL(root_service)) {
ret = OB_ERR_SYS;
LOG_WARN("error sys, root service must not be nullptr", K(ret));
is_ddl_retryable_ = true;
if (OB_ISNULL(table_schema)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguments", K(ret), KP(table_schema));
} else if (OB_FAIL(check_use_heap_table_ddl_plan(table_schema))) {
LOG_WARN("check use heap table ddl plan failed", K(ret));
} else if (DDL_MVIEW_COMPLETE_REFRESH == task_type_) {
is_ddl_retryable_ = false;
} else {
if (ObDDLUtil::use_idempotent_mode(data_format_version_)) {
if (use_heap_table_ddl_plan_) {
is_ddl_retryable_ = false;
} else if (DDL_MODIFY_AUTO_INCREMENT_WITH_REDEFINITION == task_type_) {
is_ddl_retryable_ = false;
}
}
}
return ret;
}
int ObTableRedefinitionTask::check_use_heap_table_ddl_plan(const ObTableSchema *target_table_schema)
{
int ret = OB_SUCCESS;
use_heap_table_ddl_plan_ = false;
if (OB_ISNULL(target_table_schema)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguments", K(ret), KP(target_table_schema));
} else if (OB_FAIL(DDL_SIM(tenant_id_, task_id_, TABLE_REDEF_TASK_CHECK_USE_HEAP_PLAN_FAILED))) {
LOG_WARN("ddl sim failure", K(tenant_id_), K(task_id_));
} else if (OB_FAIL(root_service->get_ddl_service()
.get_tenant_schema_guard_with_version_in_inner_table(dst_tenant_id_, schema_guard))) {
LOG_WARN("get schema guard failed", K(ret));
} else if (OB_FAIL(schema_guard.get_table_schema(dst_tenant_id_, target_object_id_, target_table_schema))) {
LOG_WARN("fail to get table schema", K(ret), K(target_object_id_));
} else if (OB_ISNULL(target_table_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("error unexpected, table schema must not be nullptr", K(ret), K(target_object_id_));
} else if (target_table_schema->is_heap_table() &&
(DDL_ALTER_PARTITION_BY == task_type_ || DDL_DROP_PRIMARY_KEY == task_type_ ||
DDL_MVIEW_COMPLETE_REFRESH == task_type_)) {
use_heap_table_ddl_plan = true;
use_heap_table_ddl_plan_ = true;
}
return ret;
}
@ -838,7 +851,6 @@ int ObTableRedefinitionTask::take_effect(const ObDDLTaskStatus next_task_status)
ObRootService *root_service = GCTX.root_service_;
ObSchemaGetterGuard schema_guard;
const ObTableSchema *table_schema = nullptr;
bool use_heap_table_ddl_plan = false;
ObDDLTaskStatus new_status = next_task_status;
if (OB_UNLIKELY(!is_inited_)) {
ret = OB_NOT_INIT;
@ -857,9 +869,7 @@ int ObTableRedefinitionTask::take_effect(const ObDDLTaskStatus next_task_status)
LOG_WARN("table schema not exist", K(ret), K(target_object_id_));
} else if (!table_schema->is_user_hidden_table()) {
LOG_INFO("target schema took effect", K(target_object_id_));
} else if (OB_FAIL(check_use_heap_table_ddl_plan(use_heap_table_ddl_plan))) {
LOG_WARN("fail to check heap table ddl plan", K(ret));
} else if (table_schema->is_heap_table() && !use_heap_table_ddl_plan && OB_FAIL(sync_tablet_autoinc_seq())) {
} else if (table_schema->is_heap_table() && !use_heap_table_ddl_plan_ && OB_FAIL(sync_tablet_autoinc_seq())) {
if (OB_TIMEOUT == ret || OB_NOT_MASTER == ret) {
ret = OB_SUCCESS;
new_status = ObDDLTaskStatus::TAKE_EFFECT;
@ -1064,7 +1074,9 @@ int64_t ObTableRedefinitionTask::get_serialize_param_size() const
+ serialization::encoded_length_i8(copy_constraints) + serialization::encoded_length_i8(copy_foreign_keys)
+ serialization::encoded_length_i8(ignore_errors) + serialization::encoded_length_i8(do_finish)
+ serialization::encoded_length_i64(target_cg_cnt_)
+ serialization::encoded_length_i64(complete_sstable_job_ret_code_);
+ serialization::encoded_length_i64(complete_sstable_job_ret_code_)
+ serialization::encoded_length_i8(use_heap_table_ddl_plan_)
+ serialization::encoded_length_i8(is_ddl_retryable_);
}
int ObTableRedefinitionTask::serialize_params_to_message(char *buf, const int64_t buf_len, int64_t &pos) const
@ -1099,6 +1111,10 @@ int ObTableRedefinitionTask::serialize_params_to_message(char *buf, const int64_
LOG_WARN("fail to serialize target_cg_cnt", K(ret));
} else if (OB_FAIL(serialization::encode_i64(buf, buf_len, pos, complete_sstable_job_ret_code_))) {
LOG_WARN("fail to serialize complete sstable job ret code", K(ret));
} else if (OB_FAIL(serialization::encode_i8(buf, buf_len, pos, use_heap_table_ddl_plan_))) {
LOG_WARN("fail to serialize use heap table ddl plan", K(ret));
} else if (OB_FAIL(serialization::encode_i8(buf, buf_len, pos, is_ddl_retryable_))) {
LOG_WARN("fail to serialize ddl can retry", K(ret));
}
FLOG_INFO("serialize message for table redefinition", K(ret),
K(copy_indexes), K(copy_triggers), K(copy_constraints), K(copy_foreign_keys), K(ignore_errors), K(do_finish), K(*this));
@ -1152,7 +1168,23 @@ int ObTableRedefinitionTask::deserlize_params_from_message(const uint64_t tenant
}
if (OB_SUCC(ret) && pos < data_len) {
if (OB_FAIL(serialization::decode_i64(buf, data_len, pos, &complete_sstable_job_ret_code_))) {
LOG_WARN("fail to deserialize is_do_finish_", K(ret));
LOG_WARN("fail to deserialize complete sstable job ret code", K(ret));
}
}
if (OB_SUCC(ret) && pos < data_len) {
int8_t use_heap_table_ddl_plan = false;
if (OB_FAIL(serialization::decode_i8(buf, data_len, pos, &use_heap_table_ddl_plan))) {
LOG_WARN("fail to deserialize use heap table ddl plan", K(ret));
} else {
use_heap_table_ddl_plan_ = use_heap_table_ddl_plan;
}
}
if (OB_SUCC(ret) && pos < data_len) {
int8_t ddl_can_retry = false;
if (OB_FAIL(serialization::decode_i8(buf, data_len, pos, &ddl_can_retry))) {
LOG_WARN("fail to deserialize ddl can retry", K(ret));
} else {
is_ddl_retryable_ = ddl_can_retry;
}
}
}

View File

@ -80,6 +80,7 @@ protected:
const int64_t row_scanned,
const int64_t row_inserted);
int repending(const share::ObDDLTaskStatus next_task_status);
virtual bool task_can_retry() const override { return is_ddl_retryable_; }
private:
inline bool get_is_copy_indexes() const {return is_copy_indexes_;}
inline bool get_is_copy_triggers() const {return is_copy_triggers_;}
@ -95,9 +96,10 @@ private:
int check_build_replica_end(bool &is_end);
int replica_end_check(const int ret_code);
int check_modify_autoinc(bool &modify_autoinc);
int check_use_heap_table_ddl_plan(bool &use_heap_table_ddl_plan);
int check_use_heap_table_ddl_plan(const share::schema::ObTableSchema *target_table_schema);
int get_direct_load_job_stat(common::ObArenaAllocator &allocator, sql::ObLoadDataStat &job_stat);
int check_target_cg_cnt();
int check_ddl_can_retry(const share::schema::ObTableSchema *table_schema);
private:
static const int64_t OB_TABLE_REDEFINITION_TASK_VERSION = 1L;
bool has_rebuild_index_;
@ -111,6 +113,8 @@ private:
bool is_ignore_errors_;
bool is_do_finish_;
int64_t target_cg_cnt_;
bool use_heap_table_ddl_plan_;
bool is_ddl_retryable_;
};
} // end namespace rootserver

View File

@ -0,0 +1,239 @@
/**
* 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 RS
#include "rootserver/mview/ob_mview_dependency_service.h"
#include "share/schema/ob_multi_version_schema_service.h"
#include "share/schema/ob_schema_getter_guard.h"
#include "share/schema/ob_table_sql_service.h"
#include "sql/resolver/mv/ob_mv_dep_utils.h"
namespace oceanbase
{
using namespace share;
using namespace share::schema;
using namespace sql;
namespace rootserver
{
ObMViewDependencyService::ObMViewDependencyService(ObMultiVersionSchemaService &schema_service)
: schema_service_(schema_service)
{
}
ObMViewDependencyService::~ObMViewDependencyService()
{
}
int ObMViewDependencyService::remove_mview_dep_infos(
common::ObMySQLTransaction &trans,
share::schema::ObSchemaGetterGuard &schema_guard,
const uint64_t tenant_id,
const uint64_t mview_table_id)
{
int ret = OB_SUCCESS;
ObArray<uint64_t> stale_ref_table_ids;
// during upgrading, dropping mview should still work,
// hence, do nothing if __all_mview_dep does not exists
bool all_mview_dep_table_exists = false;
if (OB_FAIL(share::schema::ObSchemaUtils::check_sys_table_exist_by_sql(
trans, tenant_id, OB_ALL_MVIEW_DEP_TID, all_mview_dep_table_exists))) {
LOG_WARN("failed to check whether __all_mview_dep table exists", KR(ret));
} else if (all_mview_dep_table_exists) {
if (OB_FAIL(ObMVDepUtils::get_table_ids_only_referenced_by_given_mv(
trans, tenant_id, mview_table_id, stale_ref_table_ids))) {
LOG_WARN("failed to get table ids only referenced by given mv", KR(ret));
} else if (!stale_ref_table_ids.empty()) {
enum ObTableReferencedByMVFlag table_ref_by_mv_flag =
ObTableReferencedByMVFlag::IS_NOT_REFERENCED_BY_MV;
if (OB_FAIL(update_mview_reference_table_status(trans,
schema_guard,
tenant_id,
stale_ref_table_ids,
table_ref_by_mv_flag))) {
LOG_WARN("failed to update mview reference table status", KR(ret));
}
}
if (OB_SUCC(ret) && OB_FAIL(sql::ObMVDepUtils::delete_mview_dep_infos(
trans, tenant_id, mview_table_id))) {
LOG_WARN("failed to delete mview dep infos", KR(ret), K(mview_table_id));
}
}
return ret;
}
int ObMViewDependencyService::update_mview_dep_infos(
ObMySQLTransaction &trans,
ObSchemaGetterGuard &schema_guard,
const uint64_t tenant_id,
const uint64_t mview_table_id,
const common::ObIArray<ObDependencyInfo> &dep_infos)
{
int ret = OB_SUCCESS;
ObArray<ObMVDepInfo> cur_mv_dep_infos;
ObArray<ObMVDepInfo> prev_mv_dep_infos;
ObArray<uint64_t> new_ref_table_ids;// table_referenced_by_mv_flag will be set
ObArray<uint64_t> stale_ref_table_ids; // table_referenced_by_mv_flag will be cleared
ObArray<uint64_t> table_ids_only_ref_by_this_mv;
// during upgrading, creating mview should still work,
// hence, do nothing if __all_mview_dep does not exists
bool all_mview_dep_table_exists = false;
if ((OB_INVALID_TENANT_ID == tenant_id) || (OB_INVALID_ID == mview_table_id)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid tenant_id or mview_table_id", KR(ret), K(tenant_id), K(mview_table_id));
} else if (OB_FAIL(share::schema::ObSchemaUtils::check_sys_table_exist_by_sql(
trans, tenant_id, OB_ALL_MVIEW_DEP_TID, all_mview_dep_table_exists))) {
LOG_WARN("failed to check is system table name", KR(ret));
} else if (all_mview_dep_table_exists) {
if (OB_FAIL(sql::ObMVDepUtils::convert_to_mview_dep_infos(dep_infos, cur_mv_dep_infos))) {
LOG_WARN("failed to convert to mview dep infos", KR(ret));
} else if (OB_FAIL(sql::ObMVDepUtils::get_mview_dep_infos(
trans, tenant_id, mview_table_id, prev_mv_dep_infos))) {
LOG_WARN("failed to get mview dep infos", KR(ret));
} else if (OB_FAIL(ObMVDepUtils::get_table_ids_only_referenced_by_given_mv(
trans, tenant_id, mview_table_id, table_ids_only_ref_by_this_mv))) {
LOG_WARN("failed to get table ids only referenced by given mv", KR(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && (i < cur_mv_dep_infos.count()); ++i) {
const ObMVDepInfo &cur_mv_dep = cur_mv_dep_infos.at(i);
if (OB_FAIL(new_ref_table_ids.push_back(cur_mv_dep.p_obj_))) {
LOG_WARN("failed to add cur ref table id to array", KR(ret));
}
}
}
if (OB_FAIL(ret)) {
} else if (prev_mv_dep_infos.empty()) { // creating a new mview
} else if (OB_UNLIKELY(prev_mv_dep_infos.count() != cur_mv_dep_infos.count())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("mv dep infos count not match",
KR(ret), K(prev_mv_dep_infos), K(cur_mv_dep_infos));
} else { // updating an existing mview
for (int64_t i = 0; OB_SUCC(ret) && (i < cur_mv_dep_infos.count()); ++i) {
const ObMVDepInfo &prev_mv_dep = prev_mv_dep_infos.at(i);
const ObMVDepInfo &cur_mv_dep = cur_mv_dep_infos.at(i);
if (OB_UNLIKELY(prev_mv_dep.p_order_ != cur_mv_dep.p_order_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("p_order is not match",
KR(ret), K(prev_mv_dep.p_order_), K(cur_mv_dep.p_order_));
} else if (prev_mv_dep.p_obj_ != cur_mv_dep.p_obj_) {
const uint64_t old_ref_table_id = prev_mv_dep.p_obj_;
// if an old_ref_table_id exists in the cur_mv_dep_infos,
// then its table_referenced_by_mv_flag does not need to be cleared
if (has_exist_in_array(new_ref_table_ids, old_ref_table_id)) {
} else if (has_exist_in_array(table_ids_only_ref_by_this_mv, prev_mv_dep.p_obj_)) {
// only when an old_ref_table_id exists in the list of table_ids_only_ref_by_this_mv,
// its table_referenced_by_mv_flag needs to be cleared
if (OB_FAIL(stale_ref_table_ids.push_back(prev_mv_dep.p_obj_))) {
LOG_WARN("failed to add old ref table id to array", KR(ret), K(prev_mv_dep.p_obj_));
}
}
}
}
}
if (OB_SUCC(ret) && !stale_ref_table_ids.empty()) {
enum ObTableReferencedByMVFlag table_ref_by_mv_flag =
ObTableReferencedByMVFlag::IS_NOT_REFERENCED_BY_MV;
if (OB_FAIL(update_mview_reference_table_status(trans,
schema_guard,
tenant_id,
stale_ref_table_ids,
table_ref_by_mv_flag))) {
LOG_WARN("failed to update mview reference table status", KR(ret));
}
}
if (OB_SUCC(ret) && !new_ref_table_ids.empty()) {
enum ObTableReferencedByMVFlag table_ref_by_mv_flag =
ObTableReferencedByMVFlag::IS_REFERENCED_BY_MV;
if (OB_FAIL(sql::ObMVDepUtils::delete_mview_dep_infos(
trans, tenant_id, mview_table_id))) {
LOG_WARN("failed to delete mview dep infos", KR(ret), K(mview_table_id));
} else if (OB_FAIL(sql::ObMVDepUtils::insert_mview_dep_infos(
trans, tenant_id, mview_table_id, cur_mv_dep_infos))) {
LOG_WARN("failed to insert mview dep infos", KR(ret), K(new_ref_table_ids));
} else if (OB_FAIL(update_mview_reference_table_status(trans,
schema_guard,
tenant_id,
new_ref_table_ids,
table_ref_by_mv_flag))) {
LOG_WARN("failed to update mview reference table status",
KR(ret), K(table_ref_by_mv_flag ));
}
}
}
return ret;
}
int ObMViewDependencyService::update_mview_reference_table_status(
ObMySQLTransaction &trans,
ObSchemaGetterGuard &schema_guard,
const uint64_t tenant_id,
const ObIArray<uint64_t> &ref_table_ids,
enum ObTableReferencedByMVFlag table_flag)
{
int ret = OB_SUCCESS;
uint64_t compat_version = 0;
if ((ObTableReferencedByMVFlag::IS_REFERENCED_BY_MV != table_flag)
&& (ObTableReferencedByMVFlag::IS_NOT_REFERENCED_BY_MV != table_flag)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid table_flag", KR(ret), K(table_flag));
} else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, compat_version))) {
LOG_WARN("failed to get data version", KR(ret), K(tenant_id));
} else if (compat_version < DATA_VERSION_4_3_1_0) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("version lower than 4.3.1.0 does not support this operation", KR(ret));
LOG_USER_ERROR(OB_NOT_SUPPORTED,
"tenant's data version is below 4.3.1.0, update mview reference table status is ");
} else {
ObSchemaService *schema_service = schema_service_.get_schema_service();
for (int64_t i = 0; OB_SUCC(ret) && (i < ref_table_ids.count()); ++i) {
int64_t new_schema_version = OB_INVALID_VERSION;
const uint64_t ref_table_id = ref_table_ids.at(i);
const ObTableSchema *ref_table_schema = NULL;
if (OB_FAIL(schema_guard.get_table_schema(
tenant_id, ref_table_id, ref_table_schema))) {
LOG_WARN("failed to get table schema", KR(ret), K(tenant_id), K(ref_table_id));
} else if (OB_ISNULL(ref_table_schema)) {
// the reference table has already been dropped, ignore it
LOG_TRACE("ref table schema is null", KR(ret), K(tenant_id), K(ref_table_id));
} else if (table_flag == ObTableMode::get_table_referenced_by_mv_flag(
ref_table_schema->get_table_mode())) {
// bypass
} else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) {
LOG_WARN("fail to gen new schema_version", KR(ret), K(tenant_id));
} else {
SMART_VAR(ObTableSchema, new_ref_table_schema) {
if (OB_FAIL(new_ref_table_schema.assign(*ref_table_schema))) {
LOG_WARN("fail to assign ref table schema", KR(ret));
} else {
new_ref_table_schema.set_table_id(ref_table_id);
new_ref_table_schema.set_table_referenced_by_mv(table_flag);
new_ref_table_schema.set_schema_version(new_schema_version);
if (OB_FAIL(schema_service->get_table_sql_service().update_mview_reference_table_status(
new_ref_table_schema, trans))) {
LOG_WARN("failed to update mview reference table status",
KR(ret), K(ref_table_id), K(table_flag));
}
}
}
}
}
}
return ret;
}
} // end of sql
} // end of oceanbase

View File

@ -0,0 +1,62 @@
/**
* 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_ROOTSERVER_MVIEW_OB_MVIEW_DEPENDENCY_SERVICE_H_
#define OCEANBASE_ROOTSERVER_MVIEW_OB_MVIEW_DEPENDENCY_SERVICE_H_
#include "lib/ob_define.h"
#include "lib/container/ob_array.h"
#include "share/schema/ob_table_schema.h"
namespace oceanbase
{
namespace common
{
class ObMySQLTransaction;
}
namespace share
{
namespace schema
{
class ObSchemaGetterGuard;
class ObMultiVersionSchemaService;
class ObDependencyInfo;
}
}
namespace rootserver
{
class ObMViewDependencyService
{
public:
ObMViewDependencyService(share::schema::ObMultiVersionSchemaService &schema_service);
~ObMViewDependencyService();
int update_mview_dep_infos(common::ObMySQLTransaction &trans,
share::schema::ObSchemaGetterGuard &schema_guard,
const uint64_t tenant_id,
const uint64_t mview_table_id,
const common::ObIArray<share::schema::ObDependencyInfo> &dep_infos);
int remove_mview_dep_infos(common::ObMySQLTransaction &trans,
share::schema::ObSchemaGetterGuard &schema_guard,
const uint64_t tenant_id,
const uint64_t mview_table_id);
int update_mview_reference_table_status(
common::ObMySQLTransaction &trans,
share::schema::ObSchemaGetterGuard &schema_guard,
const uint64_t tenant_id,
const ObIArray<uint64_t> &ref_table_ids,
enum share::schema::ObTableReferencedByMVFlag table_flags);
private:
share::schema::ObMultiVersionSchemaService &schema_service_;
};
} // end of sql
} // end of oceanbase
#endif

View File

@ -121,7 +121,7 @@
#include "share/schema/ob_mview_info.h"
#include "storage/mview/ob_mview_sched_job_utils.h"
#include "rootserver/restore/ob_tenant_clone_util.h"
#include "rootserver/mview/ob_mview_dependency_service.h"
namespace oceanbase
{
@ -4125,11 +4125,7 @@ int ObDDLService::check_alter_table_column(obrpc::ObAlterTableArg &alter_table_a
} else if (orig_table_schema.get_autoinc_column_id() == 0) {
if (orig_column_schema->is_nullable()) {
// if the original table has null, we need to do double write to fill the nulls
if (ObDDLType::DDL_INVALID == ddl_type || ObDDLType::DDL_MODIFY_COLUMN == ddl_type) {
ddl_type = ObDDLType::DDL_MODIFY_COLUMN;
} else {
ddl_type = ObDDLType::DDL_TABLE_REDEFINITION;
}
ddl_type = ObDDLType::DDL_MODIFY_AUTO_INCREMENT_WITH_REDEFINITION;
} else {
if (ObDDLType::DDL_INVALID == ddl_type) {
ddl_type = ObDDLType::DDL_MODIFY_AUTO_INCREMENT;
@ -13298,6 +13294,7 @@ int ObDDLService::do_offline_ddl_in_trans(obrpc::ObAlterTableArg &alter_table_ar
LOG_WARN("submit ddl task failed", K(ret));
} else {
res.task_id_ = task_record.task_id_;
res.ddl_need_retry_at_executor_ = task_record.ddl_need_retry_at_executor_;
}
} else if (is_simple_table_long_running_ddl(ddl_type)) {
ObCreateDDLTaskParam param(tenant_id,
@ -13317,6 +13314,7 @@ int ObDDLService::do_offline_ddl_in_trans(obrpc::ObAlterTableArg &alter_table_ar
LOG_WARN("submit ddl task failed", K(ret));
} else {
res.task_id_ = task_record.task_id_;
res.ddl_need_retry_at_executor_ = task_record.ddl_need_retry_at_executor_;
}
} else {
ret = OB_ERR_UNEXPECTED;
@ -13394,6 +13392,7 @@ int ObDDLService::create_hidden_table(
int64_t refreshed_schema_version = 0;
new_table_schema.set_tenant_id(dest_tenant_id);
new_table_schema.set_table_state_flag(ObTableStateFlag::TABLE_STATE_OFFLINE_DDL);
new_table_schema.set_table_referenced_by_mv(ObTableReferencedByMVFlag::IS_NOT_REFERENCED_BY_MV);
if (OB_FAIL(schema_guard.get_schema_version(tenant_id, refreshed_schema_version))) {
LOG_WARN("failed to get tenant schema version", KR(ret), K(tenant_id));
} else if (OB_FAIL(trans.start(sql_proxy_, tenant_id, refreshed_schema_version))) {
@ -18733,6 +18732,14 @@ int ObDDLService::swap_orig_and_hidden_table_state(obrpc::ObAlterTableArg &alter
LOG_WARN("fail to insert schema object dependency", KR(ret), K(dep));
}
}
if (OB_SUCC(ret)) {
ObMViewDependencyService mv_dep_service(*schema_service_);
if (OB_FAIL(mv_dep_service.update_mview_dep_infos(
trans, schema_guard, tenant_id, mview_table_id, deps))) {
LOG_WARN("failed to update mview dep infos", KR(ret));
}
}
}
// update mview_info
if (OB_SUCC(ret)) {
@ -21276,6 +21283,15 @@ int ObDDLService::drop_table_in_trans(
table_schema, MATERIALIZED_VIEW, false)))) {
LOG_WARN("drop_aux_table_in_drop_table failed", KR(ret));
}
if (OB_SUCC(ret)) {
const uint64_t mview_table_id = table_schema.get_table_id();
ObMViewDependencyService mv_dep_service(*schema_service_);
if (OB_FAIL(mv_dep_service.remove_mview_dep_infos(
trans, schema_guard, tenant_id, mview_table_id))) {
LOG_WARN("failed to remove mview dep infos", KR(ret));
}
}
} else if (!table_schema.is_aux_table()) {
if (OB_FAIL((drop_aux_table_in_drop_table(trans, ddl_operator, schema_guard,
table_schema, USER_INDEX, to_recyclebin)))) {
@ -39018,6 +39034,5 @@ bool ObDDLService::need_modify_dep_obj_status(const obrpc::ObAlterTableArg &alte
|| (alter_table_arg.is_alter_options_
&& alter_table_schema.alter_option_bitset_.has_member(ObAlterTableArg::TABLE_NAME)));
}
} // end namespace rootserver
} // end namespace oceanbase

View File

@ -29,7 +29,8 @@ namespace rootserver
{
ObMLogBuilder::MLogColumnUtils::MLogColumnUtils()
: mlog_table_column_array_(),
allocator_("MlogColUtil")
allocator_("MlogColUtil"),
rowkey_count_(0)
{
}
@ -85,11 +86,10 @@ int ObMLogBuilder::MLogColumnUtils::check_column_type(
return ret;
}
int ObMLogBuilder::MLogColumnUtils::add_special_columns(
ObTableSchema &mlog_schema)
int ObMLogBuilder::MLogColumnUtils::add_special_columns()
{
int ret = OB_SUCCESS;
if (OB_FAIL(add_pk_column(mlog_schema))) {
if (OB_FAIL(add_sequence_column())) {
LOG_WARN("failed to add sequence column", KR(ret));
} else if (OB_FAIL(add_dmltype_column())) {
LOG_WARN("failed to add dmltype column", KR(ret));
@ -99,9 +99,9 @@ int ObMLogBuilder::MLogColumnUtils::add_special_columns(
return ret;
}
// sequence column is mlog's rowkey
int ObMLogBuilder::MLogColumnUtils::add_pk_column(
ObTableSchema &mlog_schema)
// sequence_no is part of mlog's rowkey
// its rowkey position will be set later
int ObMLogBuilder::MLogColumnUtils::add_sequence_column()
{
int ret = OB_SUCCESS;
ObColumnSchemaV2 *rowkey_column = nullptr;
@ -111,17 +111,16 @@ int ObMLogBuilder::MLogColumnUtils::add_pk_column(
rowkey_column->set_autoincrement(false);
rowkey_column->set_is_hidden(false);
rowkey_column->set_nullable(false);
rowkey_column->set_rowkey_position(1);
rowkey_column->set_rowkey_position(0);
rowkey_column->set_order_in_rowkey(ObOrderType::ASC);
rowkey_column->set_column_id(OB_MLOG_SEQ_NO_COLUMN_ID);
rowkey_column->set_data_type(ObIntType);
rowkey_column->set_charset_type(CHARSET_BINARY);
rowkey_column->set_collation_type(CS_TYPE_BINARY);
mlog_schema.set_rowkey_column_num(1);
if (OB_FAIL(rowkey_column->set_column_name(OB_MLOG_SEQ_NO_COLUMN_NAME))) {
LOG_WARN("failed to set column name", KR(ret));
} else if (OB_FAIL(mlog_schema.add_column(*rowkey_column))) {
LOG_WARN("failed to add rowkey column to mlog schema", KR(ret));
} else if (OB_FAIL(mlog_table_column_array_.push_back(rowkey_column))) {
LOG_WARN("failed to push back column to mlog table column array", KR(ret), KPC(rowkey_column));
}
}
return ret;
@ -201,9 +200,9 @@ int ObMLogBuilder::MLogColumnUtils::add_base_table_pk_columns(
LOG_WARN("failed to assign rowkey_column to ref_column",
KR(ret), KPC(rowkey_column));
} else {
// preserve the rowkey position of the column
ref_column->set_autoincrement(false);
ref_column->set_is_hidden(false);
ref_column->set_rowkey_position(0);
ref_column->set_index_position(0);
ref_column->set_prev_column_id(UINT64_MAX);
ref_column->set_next_column_id(UINT64_MAX);
@ -215,6 +214,8 @@ int ObMLogBuilder::MLogColumnUtils::add_base_table_pk_columns(
} else if (OB_FAIL(mlog_table_column_array_.push_back(ref_column))) {
LOG_WARN("failed to push back column to mlog table column array",
KR(ret), KP(ref_column));
} else {
++rowkey_count_;
}
}
}
@ -269,7 +270,7 @@ int ObMLogBuilder::MLogColumnUtils::add_base_table_columns(
return ret;
}
int ObMLogBuilder::MLogColumnUtils::add_base_table_part_key_columns(
int ObMLogBuilder::MLogColumnUtils::implicit_add_base_table_part_key_columns(
const ObPartitionKeyInfo &part_key_info,
ObRowDesc &row_desc,
const ObTableSchema &base_table_schema)
@ -327,12 +328,12 @@ int ObMLogBuilder::MLogColumnUtils::add_base_table_part_key_columns(
int ret = OB_SUCCESS;
const ObPartitionKeyInfo &part_key_info = base_table_schema.get_partition_key_info();
const ObPartitionKeyInfo &sub_part_key_info = base_table_schema.get_subpartition_key_info();
if (OB_FAIL(add_base_table_part_key_columns(
if (OB_FAIL(implicit_add_base_table_part_key_columns(
part_key_info, row_desc, base_table_schema))) {
LOG_WARN("failed to add base table part key columns", KR(ret));
} else if (OB_FAIL(add_base_table_part_key_columns(
LOG_WARN("failed to implicit add base table part key columns", KR(ret));
} else if (OB_FAIL(implicit_add_base_table_part_key_columns(
sub_part_key_info, row_desc, base_table_schema))) {
LOG_WARN("failed to add base table sub part key columns", KR(ret));
LOG_WARN("failed to implicit add base table sub part key columns", KR(ret));
}
return ret;
}
@ -350,7 +351,6 @@ int ObMLogBuilder::MLogColumnUtils::construct_mlog_table_columns(
ObTableSchema &mlog_schema)
{
int ret = OB_SUCCESS;
int64_t rowkey_pos = 1; // the first rowkey is seq_no
// sort mlog_table_column_array first
struct ColumnSchemaCmp {
inline bool operator()(const ObColumnSchemaV2 *a, const ObColumnSchemaV2 *b) {
@ -361,8 +361,13 @@ int ObMLogBuilder::MLogColumnUtils::construct_mlog_table_columns(
for (int64_t i = 0; OB_SUCC(ret) && (i < mlog_table_column_array_.count()); ++i) {
ObColumnSchemaV2 *column = mlog_table_column_array_.at(i);
if (column->is_part_key_column() || column->is_subpart_key_column()) {
column->set_rowkey_position(++rowkey_pos);
// columns referencing base table primary keys have already been assigned rowkey position
if ((column->is_part_key_column() || column->is_subpart_key_column())
&& (0 == column->get_rowkey_position())) {
column->set_rowkey_position(++rowkey_count_);
} else if (OB_MLOG_SEQ_NO_COLUMN_ID == column->get_column_id()) {
// mlog seq_no column must be the last rowkey
column->set_rowkey_position(++rowkey_count_);
}
if (OB_FAIL(mlog_schema.add_column(*column))) {
LOG_WARN("failed to add column to mlog schema", KR(ret), KPC(column));
@ -686,50 +691,44 @@ int ObMLogBuilder::set_table_columns(
LOG_WARN("ObMLogBuilder not init", KR(ret));
} else {
HEAP_VAR(ObRowDesc, row_desc) {
if (OB_FAIL(mlog_column_utils_.add_special_columns(mlog_schema))) {
if (base_table_schema.is_heap_table()) {
if (create_mlog_arg.with_primary_key_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("create mlog on heap table cannot use with primary key option",
KR(ret), K(base_table_schema.is_heap_table()), K(create_mlog_arg.with_primary_key_));
} else if (!create_mlog_arg.with_rowid_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("create mlog on heap table should use with rowid option",
KR(ret), K(base_table_schema.is_heap_table()), K(create_mlog_arg.with_rowid_));
}
} else {
if (create_mlog_arg.with_rowid_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("create mlog on non-heap table cannot use with rowid option",
KR(ret), K(base_table_schema.is_heap_table()), K(create_mlog_arg.with_rowid_));
} else if (!create_mlog_arg.with_primary_key_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("create mlog on non-heap table should use with primary key option",
KR(ret), K(base_table_schema.is_heap_table()), K(create_mlog_arg.with_primary_key_));
}
}
// the primary key of a mlog is consist of:
// the base table pk + the base table part key + the mlog sequence no
if (OB_FAIL(ret)) {
} else if (OB_FAIL(mlog_column_utils_.add_base_table_pk_columns(
row_desc, base_table_schema))) {
LOG_WARN("failed to add base table pk columns", KR(ret));
} else if (OB_FAIL(mlog_column_utils_.add_base_table_columns(
create_mlog_arg, row_desc, base_table_schema))) {
LOG_WARN("failed to add base table columns", KR(ret));
} else if (OB_FAIL(mlog_column_utils_.add_base_table_part_key_columns(
row_desc, base_table_schema))) {
LOG_WARN("failed to add base table part key columns", KR(ret));
} else if (OB_FAIL(mlog_column_utils_.add_special_columns())) {
LOG_WARN("failed to add special columns", KR(ret));
}
if (OB_SUCC(ret)) {
if (base_table_schema.is_heap_table()) {
if (create_mlog_arg.with_primary_key_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("create mlog on heap table cannot use with primary key option",
KR(ret), K(base_table_schema.is_heap_table()), K(create_mlog_arg.with_primary_key_));
} else if (!create_mlog_arg.with_rowid_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("create mlog on heap table should use with rowid option",
KR(ret), K(base_table_schema.is_heap_table()), K(create_mlog_arg.with_rowid_));
}
} else {
if (create_mlog_arg.with_rowid_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("create mlog on non-heap table cannot use with rowid option",
KR(ret), K(base_table_schema.is_heap_table()), K(create_mlog_arg.with_rowid_));
} else if (!create_mlog_arg.with_primary_key_) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("create mlog on non-heap table should use with primary key option",
KR(ret), K(base_table_schema.is_heap_table()), K(create_mlog_arg.with_primary_key_));
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(mlog_column_utils_.add_base_table_pk_columns(
row_desc, base_table_schema))) {
LOG_WARN("failed to add base table pk columns", KR(ret));
}
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(mlog_column_utils_.add_base_table_columns(
create_mlog_arg, row_desc, base_table_schema))) {
LOG_WARN("failed to add base table columns", KR(ret));
} else if (OB_FAIL(mlog_column_utils_.add_base_table_part_key_columns(
row_desc, base_table_schema))) {
LOG_WARN("failed to add base table part key columns", KR(ret));
} else if (OB_FAIL(mlog_column_utils_.construct_mlog_table_columns(mlog_schema))) {
LOG_WARN("failed to construct mlog table columns", KR(ret));
}
} else if (OB_FAIL(mlog_column_utils_.construct_mlog_table_columns(mlog_schema))) {
LOG_WARN("failed to construct mlog table columns", KR(ret));
}
}
}

View File

@ -54,20 +54,22 @@ private:
const share::schema::ObTableSchema &base_table_schema);
int add_base_table_part_key_columns(common::ObRowDesc &row_desc,
const share::schema::ObTableSchema &base_table_schema);
int add_special_columns(share::schema::ObTableSchema &mlog_schema);
int add_special_columns();
int construct_mlog_table_columns(share::schema::ObTableSchema &mlog_schema);
private:
int add_pk_column(share::schema::ObTableSchema &mlog_schema);
int add_sequence_column();
int add_dmltype_column();
int add_old_new_column();
int add_base_table_part_key_columns(const common::ObPartitionKeyInfo &part_key_info,
common::ObRowDesc &row_desc,
const share::schema::ObTableSchema &base_table_schema);
int implicit_add_base_table_part_key_columns(
const common::ObPartitionKeyInfo &part_key_info,
common::ObRowDesc &row_desc,
const share::schema::ObTableSchema &base_table_schema);
int alloc_column(ObColumnSchemaV2 *&column);
public:
ObArray<ObColumnSchemaV2 *> mlog_table_column_array_;
private:
ObArenaAllocator allocator_;
int64_t rowkey_count_;
};
private:

View File

@ -1035,6 +1035,203 @@ int ObInnerTableSchema::all_tenant_snapshot_ls_replica_history_schema(ObTableSch
return ret;
}
int ObInnerTableSchema::all_mview_dep_schema(ObTableSchema &table_schema)
{
int ret = OB_SUCCESS;
uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1;
//generated fields:
table_schema.set_tenant_id(OB_SYS_TENANT_ID);
table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID);
table_schema.set_database_id(OB_SYS_DATABASE_ID);
table_schema.set_table_id(OB_ALL_MVIEW_DEP_TID);
table_schema.set_rowkey_split_pos(0);
table_schema.set_is_use_bloomfilter(false);
table_schema.set_progressive_merge_num(0);
table_schema.set_rowkey_column_num(3);
table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK);
table_schema.set_table_type(SYSTEM_TABLE);
table_schema.set_index_type(INDEX_TYPE_IS_NOT);
table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL);
if (OB_SUCC(ret)) {
if (OB_FAIL(table_schema.set_table_name(OB_ALL_MVIEW_DEP_TNAME))) {
LOG_ERROR("fail to set table_name", K(ret));
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) {
LOG_ERROR("fail to set compress_func_name", K(ret));
}
}
table_schema.set_part_level(PARTITION_LEVEL_ZERO);
table_schema.set_charset_type(ObCharset::get_default_charset());
table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset()));
if (OB_SUCC(ret)) {
ObObj gmt_create_default;
ObObj gmt_create_default_null;
gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG);
gmt_create_default_null.set_null();
ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name
++column_id, //column_id
0, //rowkey_id
0, //index_id
0, //part_key_pos
ObTimestampType, //column_type
CS_TYPE_BINARY,//collation_type
0, //column length
-1, //column_precision
6, //column_scale
true,//is nullable
false, //is_autoincrement
false, //is_on_update_for_timestamp
gmt_create_default_null,
gmt_create_default)
}
if (OB_SUCC(ret)) {
ObObj gmt_modified_default;
ObObj gmt_modified_default_null;
gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG);
gmt_modified_default_null.set_null();
ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name
++column_id, //column_id
0, //rowkey_id
0, //index_id
0, //part_key_pos
ObTimestampType, //column_type
CS_TYPE_BINARY,//collation_type
0, //column length
-1, //column_precision
6, //column_scale
true,//is nullable
false, //is_autoincrement
true, //is_on_update_for_timestamp
gmt_modified_default_null,
gmt_modified_default)
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("tenant_id", //column_name
++column_id, //column_id
1, //rowkey_id
0, //index_id
0, //part_key_pos
ObIntType, //column_type
CS_TYPE_INVALID, //column_collation_type
sizeof(int64_t), //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("mview_id", //column_name
++column_id, //column_id
2, //rowkey_id
0, //index_id
0, //part_key_pos
ObIntType, //column_type
CS_TYPE_INVALID, //column_collation_type
sizeof(int64_t), //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("p_order", //column_name
++column_id, //column_id
3, //rowkey_id
0, //index_id
0, //part_key_pos
ObIntType, //column_type
CS_TYPE_INVALID, //column_collation_type
sizeof(int64_t), //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("p_obj", //column_name
++column_id, //column_id
0, //rowkey_id
0, //index_id
0, //part_key_pos
ObIntType, //column_type
CS_TYPE_INVALID, //column_collation_type
sizeof(int64_t), //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("p_type", //column_name
++column_id, //column_id
0, //rowkey_id
0, //index_id
0, //part_key_pos
ObIntType, //column_type
CS_TYPE_INVALID, //column_collation_type
sizeof(int64_t), //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("qbcid", //column_name
++column_id, //column_id
0, //rowkey_id
0, //index_id
0, //part_key_pos
ObIntType, //column_type
CS_TYPE_INVALID, //column_collation_type
sizeof(int64_t), //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("flags", //column_name
++column_id, //column_id
0, //rowkey_id
0, //index_id
0, //part_key_pos
ObIntType, //column_type
CS_TYPE_INVALID, //column_collation_type
sizeof(int64_t), //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
table_schema.set_index_using_type(USING_BTREE);
table_schema.set_row_store_type(ENCODING_ROW_STORE);
table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL);
table_schema.set_progressive_merge_round(1);
table_schema.set_storage_format_version(3);
table_schema.set_tablet_id(OB_ALL_MVIEW_DEP_TID);
table_schema.set_aux_lob_meta_tid(OB_ALL_MVIEW_DEP_AUX_LOB_META_TID);
table_schema.set_aux_lob_piece_tid(OB_ALL_MVIEW_DEP_AUX_LOB_PIECE_TID);
table_schema.set_max_used_column_id(column_id);
return ret;
}
} // end namespace share
} // end namespace oceanbase

View File

@ -700,6 +700,141 @@ int ObInnerTableSchema::all_tenant_snapshot_ls_replica_history_aux_lob_meta_sche
return ret;
}
int ObInnerTableSchema::all_mview_dep_aux_lob_meta_schema(ObTableSchema &table_schema)
{
int ret = OB_SUCCESS;
uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1;
//generated fields:
table_schema.set_tenant_id(OB_SYS_TENANT_ID);
table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID);
table_schema.set_database_id(OB_SYS_DATABASE_ID);
table_schema.set_table_id(OB_ALL_MVIEW_DEP_AUX_LOB_META_TID);
table_schema.set_rowkey_split_pos(0);
table_schema.set_is_use_bloomfilter(false);
table_schema.set_progressive_merge_num(0);
table_schema.set_rowkey_column_num(2);
table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK);
table_schema.set_table_type(AUX_LOB_META);
table_schema.set_index_type(INDEX_TYPE_IS_NOT);
table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL);
if (OB_SUCC(ret)) {
if (OB_FAIL(table_schema.set_table_name(OB_ALL_MVIEW_DEP_AUX_LOB_META_TNAME))) {
LOG_ERROR("fail to set table_name", K(ret));
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) {
LOG_ERROR("fail to set compress_func_name", K(ret));
}
}
table_schema.set_part_level(PARTITION_LEVEL_ZERO);
table_schema.set_charset_type(ObCharset::get_default_charset());
table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset()));
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("lob_id", //column_name
++column_id, //column_id
1, //rowkey_id
0, //index_id
0, //part_key_pos
ObVarcharType, //column_type
CS_TYPE_BINARY, //column_collation_type
16, //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("seq_id", //column_name
++column_id, //column_id
2, //rowkey_id
0, //index_id
0, //part_key_pos
ObVarcharType, //column_type
CS_TYPE_BINARY, //column_collation_type
8192, //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("binary_len", //column_name
++column_id, //column_id
0, //rowkey_id
0, //index_id
0, //part_key_pos
ObUInt32Type, //column_type
CS_TYPE_INVALID, //column_collation_type
sizeof(uint32_t), //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("char_len", //column_name
++column_id, //column_id
0, //rowkey_id
0, //index_id
0, //part_key_pos
ObUInt32Type, //column_type
CS_TYPE_INVALID, //column_collation_type
sizeof(uint32_t), //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("piece_id", //column_name
++column_id, //column_id
0, //rowkey_id
0, //index_id
0, //part_key_pos
ObUInt64Type, //column_type
CS_TYPE_INVALID, //column_collation_type
sizeof(uint64_t), //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("lob_data", //column_name
++column_id, //column_id
0, //rowkey_id
0, //index_id
0, //part_key_pos
ObVarcharType, //column_type
CS_TYPE_BINARY, //column_collation_type
262144, //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
table_schema.set_index_using_type(USING_BTREE);
table_schema.set_row_store_type(ENCODING_ROW_STORE);
table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL);
table_schema.set_progressive_merge_round(1);
table_schema.set_storage_format_version(3);
table_schema.set_tablet_id(OB_ALL_MVIEW_DEP_AUX_LOB_META_TID);
table_schema.set_data_table_id(OB_ALL_MVIEW_DEP_TID);
table_schema.set_max_used_column_id(column_id);
return ret;
}
} // end namespace share
} // end namespace oceanbase

View File

@ -475,6 +475,96 @@ int ObInnerTableSchema::all_tenant_snapshot_ls_replica_history_aux_lob_piece_sch
return ret;
}
int ObInnerTableSchema::all_mview_dep_aux_lob_piece_schema(ObTableSchema &table_schema)
{
int ret = OB_SUCCESS;
uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1;
//generated fields:
table_schema.set_tenant_id(OB_SYS_TENANT_ID);
table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID);
table_schema.set_database_id(OB_SYS_DATABASE_ID);
table_schema.set_table_id(OB_ALL_MVIEW_DEP_AUX_LOB_PIECE_TID);
table_schema.set_rowkey_split_pos(0);
table_schema.set_is_use_bloomfilter(false);
table_schema.set_progressive_merge_num(0);
table_schema.set_rowkey_column_num(1);
table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK);
table_schema.set_table_type(AUX_LOB_PIECE);
table_schema.set_index_type(INDEX_TYPE_IS_NOT);
table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL);
if (OB_SUCC(ret)) {
if (OB_FAIL(table_schema.set_table_name(OB_ALL_MVIEW_DEP_AUX_LOB_PIECE_TNAME))) {
LOG_ERROR("fail to set table_name", K(ret));
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) {
LOG_ERROR("fail to set compress_func_name", K(ret));
}
}
table_schema.set_part_level(PARTITION_LEVEL_ZERO);
table_schema.set_charset_type(ObCharset::get_default_charset());
table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset()));
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("piece_id", //column_name
++column_id, //column_id
1, //rowkey_id
0, //index_id
0, //part_key_pos
ObUInt64Type, //column_type
CS_TYPE_INVALID, //column_collation_type
sizeof(uint64_t), //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("data_len", //column_name
++column_id, //column_id
0, //rowkey_id
0, //index_id
0, //part_key_pos
ObUInt32Type, //column_type
CS_TYPE_INVALID, //column_collation_type
sizeof(uint32_t), //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
if (OB_SUCC(ret)) {
ADD_COLUMN_SCHEMA("lob_data", //column_name
++column_id, //column_id
0, //rowkey_id
0, //index_id
0, //part_key_pos
ObVarcharType, //column_type
CS_TYPE_BINARY, //column_collation_type
32, //column_length
-1, //column_precision
-1, //column_scale
false, //is_nullable
false); //is_autoincrement
}
table_schema.set_index_using_type(USING_BTREE);
table_schema.set_row_store_type(ENCODING_ROW_STORE);
table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL);
table_schema.set_progressive_merge_round(1);
table_schema.set_storage_format_version(3);
table_schema.set_tablet_id(OB_ALL_MVIEW_DEP_AUX_LOB_PIECE_TID);
table_schema.set_data_table_id(OB_ALL_MVIEW_DEP_TID);
table_schema.set_max_used_column_id(column_id);
return ret;
}
} // end namespace share
} // end namespace oceanbase

View File

@ -585,6 +585,7 @@ public:
static int all_column_privilege_schema(share::schema::ObTableSchema &table_schema);
static int all_column_privilege_history_schema(share::schema::ObTableSchema &table_schema);
static int all_tenant_snapshot_ls_replica_history_schema(share::schema::ObTableSchema &table_schema);
static int all_mview_dep_schema(share::schema::ObTableSchema &table_schema);
static int tenant_virtual_all_table_schema(share::schema::ObTableSchema &table_schema);
static int tenant_virtual_table_column_schema(share::schema::ObTableSchema &table_schema);
static int tenant_virtual_table_index_schema(share::schema::ObTableSchema &table_schema);
@ -2469,6 +2470,7 @@ public:
static int all_column_privilege_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema);
static int all_column_privilege_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema);
static int all_tenant_snapshot_ls_replica_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema);
static int all_mview_dep_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema);
static int all_table_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema);
static int all_column_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema);
static int all_ddl_operation_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema);
@ -2762,6 +2764,7 @@ public:
static int all_column_privilege_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema);
static int all_column_privilege_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema);
static int all_tenant_snapshot_ls_replica_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema);
static int all_mview_dep_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema);
static int all_virtual_ash_all_virtual_ash_i1_schema(share::schema::ObTableSchema &table_schema);
static int all_virtual_sql_plan_monitor_all_virtual_sql_plan_monitor_i1_schema(share::schema::ObTableSchema &table_schema);
static int all_virtual_sql_audit_all_virtual_sql_audit_i1_schema(share::schema::ObTableSchema &table_schema);
@ -3266,6 +3269,7 @@ const schema_create_func sys_table_schema_creators [] = {
ObInnerTableSchema::all_column_privilege_schema,
ObInnerTableSchema::all_column_privilege_history_schema,
ObInnerTableSchema::all_tenant_snapshot_ls_replica_history_schema,
ObInnerTableSchema::all_mview_dep_schema,
NULL,};
const schema_create_func virtual_table_schema_creators [] = {
@ -5344,6 +5348,7 @@ const uint64_t tenant_space_tables [] = {
OB_ALL_COLUMN_PRIVILEGE_TID,
OB_ALL_COLUMN_PRIVILEGE_HISTORY_TID,
OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID,
OB_ALL_MVIEW_DEP_TID,
OB_TENANT_VIRTUAL_ALL_TABLE_TID,
OB_TENANT_VIRTUAL_TABLE_COLUMN_TID,
OB_TENANT_VIRTUAL_TABLE_INDEX_TID,
@ -7049,6 +7054,7 @@ const uint64_t tenant_space_tables [] = {
OB_ALL_COLUMN_PRIVILEGE_AUX_LOB_META_TID,
OB_ALL_COLUMN_PRIVILEGE_HISTORY_AUX_LOB_META_TID,
OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TID,
OB_ALL_MVIEW_DEP_AUX_LOB_META_TID,
OB_ALL_TABLE_AUX_LOB_PIECE_TID,
OB_ALL_COLUMN_AUX_LOB_PIECE_TID,
OB_ALL_DDL_OPERATION_AUX_LOB_PIECE_TID,
@ -7317,7 +7323,8 @@ const uint64_t tenant_space_tables [] = {
OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_PIECE_TID,
OB_ALL_COLUMN_PRIVILEGE_AUX_LOB_PIECE_TID,
OB_ALL_COLUMN_PRIVILEGE_HISTORY_AUX_LOB_PIECE_TID,
OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TID, };
OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TID,
OB_ALL_MVIEW_DEP_AUX_LOB_PIECE_TID, };
const uint64_t all_ora_mapping_virtual_table_org_tables [] = {
OB_ALL_VIRTUAL_SQL_AUDIT_TID,
@ -7895,6 +7902,7 @@ const char* const tenant_space_table_names [] = {
OB_ALL_COLUMN_PRIVILEGE_TNAME,
OB_ALL_COLUMN_PRIVILEGE_HISTORY_TNAME,
OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TNAME,
OB_ALL_MVIEW_DEP_TNAME,
OB_TENANT_VIRTUAL_ALL_TABLE_TNAME,
OB_TENANT_VIRTUAL_TABLE_COLUMN_TNAME,
OB_TENANT_VIRTUAL_TABLE_INDEX_TNAME,
@ -9600,6 +9608,7 @@ const char* const tenant_space_table_names [] = {
OB_ALL_COLUMN_PRIVILEGE_AUX_LOB_META_TNAME,
OB_ALL_COLUMN_PRIVILEGE_HISTORY_AUX_LOB_META_TNAME,
OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TNAME,
OB_ALL_MVIEW_DEP_AUX_LOB_META_TNAME,
OB_ALL_TABLE_AUX_LOB_PIECE_TNAME,
OB_ALL_COLUMN_AUX_LOB_PIECE_TNAME,
OB_ALL_DDL_OPERATION_AUX_LOB_PIECE_TNAME,
@ -9868,7 +9877,8 @@ const char* const tenant_space_table_names [] = {
OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_PIECE_TNAME,
OB_ALL_COLUMN_PRIVILEGE_AUX_LOB_PIECE_TNAME,
OB_ALL_COLUMN_PRIVILEGE_HISTORY_AUX_LOB_PIECE_TNAME,
OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TNAME, };
OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TNAME,
OB_ALL_MVIEW_DEP_AUX_LOB_PIECE_TNAME, };
const uint64_t only_rs_vtables [] = {
OB_ALL_VIRTUAL_CORE_META_TABLE_TID,
@ -12717,6 +12727,14 @@ LOBMapping const lob_aux_table_mappings [] = {
ObInnerTableSchema::all_tenant_snapshot_ls_replica_history_aux_lob_piece_schema
},
{
OB_ALL_MVIEW_DEP_TID,
OB_ALL_MVIEW_DEP_AUX_LOB_META_TID,
OB_ALL_MVIEW_DEP_AUX_LOB_PIECE_TID,
ObInnerTableSchema::all_mview_dep_aux_lob_meta_schema,
ObInnerTableSchema::all_mview_dep_aux_lob_piece_schema
},
};
static inline bool get_sys_table_lob_aux_table_id(const uint64_t tid, uint64_t& meta_tid, uint64_t& piece_tid)

View File

@ -321,6 +321,7 @@ const uint64_t OB_ALL_TRUSTED_ROOT_CERTIFICATE_TID = 502; // "__all_trusted_root
const uint64_t OB_ALL_COLUMN_PRIVILEGE_TID = 505; // "__all_column_privilege"
const uint64_t OB_ALL_COLUMN_PRIVILEGE_HISTORY_TID = 506; // "__all_column_privilege_history"
const uint64_t OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID = 507; // "__all_tenant_snapshot_ls_replica_history"
const uint64_t OB_ALL_MVIEW_DEP_TID = 518; // "__all_mview_dep"
const uint64_t OB_TENANT_VIRTUAL_ALL_TABLE_TID = 10001; // "__tenant_virtual_all_table"
const uint64_t OB_TENANT_VIRTUAL_TABLE_COLUMN_TID = 10002; // "__tenant_virtual_table_column"
const uint64_t OB_TENANT_VIRTUAL_TABLE_INDEX_TID = 10003; // "__tenant_virtual_table_index"
@ -2205,6 +2206,7 @@ const uint64_t OB_ALL_TRUSTED_ROOT_CERTIFICATE_AUX_LOB_META_TID = 50502; // "__a
const uint64_t OB_ALL_COLUMN_PRIVILEGE_AUX_LOB_META_TID = 50505; // "__all_column_privilege_aux_lob_meta"
const uint64_t OB_ALL_COLUMN_PRIVILEGE_HISTORY_AUX_LOB_META_TID = 50506; // "__all_column_privilege_history_aux_lob_meta"
const uint64_t OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TID = 50507; // "__all_tenant_snapshot_ls_replica_history_aux_lob_meta"
const uint64_t OB_ALL_MVIEW_DEP_AUX_LOB_META_TID = 50518; // "__all_mview_dep_aux_lob_meta"
const uint64_t OB_ALL_TABLE_AUX_LOB_PIECE_TID = 60003; // "__all_table_aux_lob_piece"
const uint64_t OB_ALL_COLUMN_AUX_LOB_PIECE_TID = 60004; // "__all_column_aux_lob_piece"
const uint64_t OB_ALL_DDL_OPERATION_AUX_LOB_PIECE_TID = 60005; // "__all_ddl_operation_aux_lob_piece"
@ -2498,6 +2500,7 @@ const uint64_t OB_ALL_TRUSTED_ROOT_CERTIFICATE_AUX_LOB_PIECE_TID = 60502; // "__
const uint64_t OB_ALL_COLUMN_PRIVILEGE_AUX_LOB_PIECE_TID = 60505; // "__all_column_privilege_aux_lob_piece"
const uint64_t OB_ALL_COLUMN_PRIVILEGE_HISTORY_AUX_LOB_PIECE_TID = 60506; // "__all_column_privilege_history_aux_lob_piece"
const uint64_t OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TID = 60507; // "__all_tenant_snapshot_ls_replica_history_aux_lob_piece"
const uint64_t OB_ALL_MVIEW_DEP_AUX_LOB_PIECE_TID = 60518; // "__all_mview_dep_aux_lob_piece"
const uint64_t OB_ALL_VIRTUAL_PLAN_CACHE_STAT_ALL_VIRTUAL_PLAN_CACHE_STAT_I1_TID = 14999; // "__all_virtual_plan_cache_stat"
const uint64_t OB_ALL_VIRTUAL_SESSION_EVENT_ALL_VIRTUAL_SESSION_EVENT_I1_TID = 14998; // "__all_virtual_session_event"
const uint64_t OB_ALL_VIRTUAL_SESSION_WAIT_ALL_VIRTUAL_SESSION_WAIT_I1_TID = 14997; // "__all_virtual_session_wait"
@ -2989,6 +2992,7 @@ const char *const OB_ALL_TRUSTED_ROOT_CERTIFICATE_TNAME = "__all_trusted_root_ce
const char *const OB_ALL_COLUMN_PRIVILEGE_TNAME = "__all_column_privilege";
const char *const OB_ALL_COLUMN_PRIVILEGE_HISTORY_TNAME = "__all_column_privilege_history";
const char *const OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TNAME = "__all_tenant_snapshot_ls_replica_history";
const char *const OB_ALL_MVIEW_DEP_TNAME = "__all_mview_dep";
const char *const OB_TENANT_VIRTUAL_ALL_TABLE_TNAME = "__tenant_virtual_all_table";
const char *const OB_TENANT_VIRTUAL_TABLE_COLUMN_TNAME = "__tenant_virtual_table_column";
const char *const OB_TENANT_VIRTUAL_TABLE_INDEX_TNAME = "__tenant_virtual_table_index";
@ -4873,6 +4877,7 @@ const char *const OB_ALL_TRUSTED_ROOT_CERTIFICATE_AUX_LOB_META_TNAME = "__all_tr
const char *const OB_ALL_COLUMN_PRIVILEGE_AUX_LOB_META_TNAME = "__all_column_privilege_aux_lob_meta";
const char *const OB_ALL_COLUMN_PRIVILEGE_HISTORY_AUX_LOB_META_TNAME = "__all_column_privilege_history_aux_lob_meta";
const char *const OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TNAME = "__all_tenant_snapshot_ls_replica_history_aux_lob_meta";
const char *const OB_ALL_MVIEW_DEP_AUX_LOB_META_TNAME = "__all_mview_dep_aux_lob_meta";
const char *const OB_ALL_TABLE_AUX_LOB_PIECE_TNAME = "__all_table_aux_lob_piece";
const char *const OB_ALL_COLUMN_AUX_LOB_PIECE_TNAME = "__all_column_aux_lob_piece";
const char *const OB_ALL_DDL_OPERATION_AUX_LOB_PIECE_TNAME = "__all_ddl_operation_aux_lob_piece";
@ -5166,6 +5171,7 @@ const char *const OB_ALL_TRUSTED_ROOT_CERTIFICATE_AUX_LOB_PIECE_TNAME = "__all_t
const char *const OB_ALL_COLUMN_PRIVILEGE_AUX_LOB_PIECE_TNAME = "__all_column_privilege_aux_lob_piece";
const char *const OB_ALL_COLUMN_PRIVILEGE_HISTORY_AUX_LOB_PIECE_TNAME = "__all_column_privilege_history_aux_lob_piece";
const char *const OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TNAME = "__all_tenant_snapshot_ls_replica_history_aux_lob_piece";
const char *const OB_ALL_MVIEW_DEP_AUX_LOB_PIECE_TNAME = "__all_mview_dep_aux_lob_piece";
const char *const OB_ALL_VIRTUAL_PLAN_CACHE_STAT_ALL_VIRTUAL_PLAN_CACHE_STAT_I1_TNAME = "__idx_11003_all_virtual_plan_cache_stat_i1";
const char *const OB_ALL_VIRTUAL_SESSION_EVENT_ALL_VIRTUAL_SESSION_EVENT_I1_TNAME = "__idx_11013_all_virtual_session_event_i1";
const char *const OB_ALL_VIRTUAL_SESSION_WAIT_ALL_VIRTUAL_SESSION_WAIT_I1_TNAME = "__idx_11014_all_virtual_session_wait_i1";

View File

@ -7128,7 +7128,26 @@ def_table_schema(**all_tenant_snapshot_ls_replica_history_def)
# 515 : __all_user_proxy_role_info_history
# 516 : __all_service
# 517 : __all_storage_io_usage
# 518 : __all_mview_dep
def_table_schema(
owner = 'yuya.yu',
table_name = '__all_mview_dep',
table_id = '518',
table_type = 'SYSTEM_TABLE',
gm_columns = ['gmt_create', 'gmt_modified'],
rowkey_columns = [
('tenant_id', 'int'),
('mview_id', 'int'),
('p_order', 'int')
],
in_tenant_space = True,
normal_columns = [
('p_obj', 'int'),
('p_type', 'int'),
('qbcid', 'int'),
('flags', 'int')
]
)
# 余留位置(此行之前占位)
# 本区域占位建议:采用真实表名进行占位

View File

@ -350,6 +350,7 @@
# 506: __all_column_privilege_history
# 506: __all_column_privilege # BASE_TABLE_NAME
# 507: __all_tenant_snapshot_ls_replica_history
# 518: __all_mview_dep
# 10001: __tenant_virtual_all_table
# 10002: __tenant_virtual_table_column
# 10003: __tenant_virtual_table_index

View File

@ -1104,6 +1104,7 @@ int ObDDLUtil::generate_build_mview_replica_sql(
ObString database_name;
ObString container_table_name;
ObSqlString src_table_schema_version_hint;
ObSqlString rowkey_column_sql_string;
if (OB_FAIL(sql::ObSQLUtils::generate_new_name_with_escape_character(
allocator, database_schema->get_database_name_str(), database_name, is_oracle_mode))) {
LOG_WARN("fail to generate new name with escape character", KR(ret),
@ -1139,29 +1140,31 @@ int ObDDLUtil::generate_build_mview_replica_sql(
}
}
if (OB_SUCC(ret)) {
int64_t real_parallelism = std::max(1L, parallelism);
int64_t real_parallelism = std::max(2L, parallelism);
real_parallelism = std::min(ObMacroDataSeq::MAX_PARALLEL_IDX + 1, real_parallelism);
const ObString &select_sql_string = mview_table_schema->get_view_schema().get_view_definition_str();
if (is_oracle_mode) {
if (OB_FAIL(sql_string.assign_fmt("INSERT /*+ monitor enable_parallel_dml parallel(%ld) opt_param('ddl_execution_id', %ld) opt_param('ddl_task_id', %ld) opt_param('enable_newsort', 'false') use_px */ INTO \"%.*s\".\"%.*s\""
" SELECT /*+ %.*s */ * from (%.*s) as of scn %ld;",
real_parallelism, execution_id, task_id,
if (OB_FAIL(sql_string.assign_fmt("INSERT /*+ append monitor enable_parallel_dml parallel(%ld) opt_param('ddl_task_id', %ld) use_px */ INTO \"%.*s\".\"%.*s\""
" SELECT /*+ %.*s */ * from (%.*s) as of scn %ld %.*s;",
real_parallelism, task_id,
static_cast<int>(database_name.length()), database_name.ptr(),
static_cast<int>(container_table_name.length()), container_table_name.ptr(),
static_cast<int>(src_table_schema_version_hint.length()), src_table_schema_version_hint.ptr(),
static_cast<int>(select_sql_string.length()), select_sql_string.ptr(),
snapshot_version))) {
snapshot_version,
static_cast<int>(rowkey_column_sql_string.length()), rowkey_column_sql_string.ptr()))) {
LOG_WARN("fail to assign sql string", KR(ret));
}
} else {
if (OB_FAIL(sql_string.assign_fmt("INSERT /*+ monitor enable_parallel_dml parallel(%ld) opt_param('ddl_execution_id', %ld) opt_param('ddl_task_id', %ld) opt_param('enable_newsort', 'false') use_px */ INTO `%.*s`.`%.*s`"
" SELECT /*+ %.*s */ * from (%.*s) as of snapshot %ld;",
real_parallelism, execution_id, task_id,
if (OB_FAIL(sql_string.assign_fmt("INSERT /*+ append monitor enable_parallel_dml parallel(%ld) opt_param('ddl_task_id', %ld) use_px */ INTO `%.*s`.`%.*s`"
" SELECT /*+ %.*s */ * from (%.*s) as of snapshot %ld %.*s;",
real_parallelism, task_id,
static_cast<int>(database_name.length()), database_name.ptr(),
static_cast<int>(container_table_name.length()), container_table_name.ptr(),
static_cast<int>(src_table_schema_version_hint.length()), src_table_schema_version_hint.ptr(),
static_cast<int>(select_sql_string.length()), select_sql_string.ptr(),
snapshot_version))) {
snapshot_version,
static_cast<int>(rowkey_column_sql_string.length()), rowkey_column_sql_string.ptr()))) {
LOG_WARN("fail to assign sql string", KR(ret));
}
}
@ -1172,6 +1175,36 @@ int ObDDLUtil::generate_build_mview_replica_sql(
return ret;
}
int ObDDLUtil::generate_order_by_str_for_mview(const ObTableSchema &container_table_schema,
ObSqlString &rowkey_column_sql_string)
{
int ret = OB_SUCCESS;
rowkey_column_sql_string.reset();
const ObRowkeyInfo &rowkey_info = container_table_schema.get_rowkey_info();
if (container_table_schema.is_heap_table()) {
/* do nothing */
} else if (OB_UNLIKELY(rowkey_info.get_size() < 1)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpcted rowkey size", K(ret), K(rowkey_info.get_size()));
} else if (OB_FAIL(rowkey_column_sql_string.append(" order by "))) {
LOG_WARN("append failed", KR(ret));
} else {
uint64_t column_id = OB_INVALID_ID;
int64_t sel_pos = 0;
for (int col_idx = 0; OB_SUCC(ret) && col_idx < rowkey_info.get_size(); ++col_idx) {
if (OB_FAIL(rowkey_info.get_column_id(col_idx, column_id))) {
LOG_WARN("Failed to get column id", K(ret));
} else if (OB_UNLIKELY(1 > (sel_pos = column_id - OB_APP_MIN_COLUMN_ID + 1))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpcted select position", K(ret), K(sel_pos), K(column_id));
} else if (OB_FAIL(rowkey_column_sql_string.append_fmt("%s %ld", 0 != col_idx ? ",": "", sel_pos))) {
LOG_WARN("append fmt failed", K(ret));
}
}
}
return ret;
}
int ObDDLUtil::get_tablet_leader_addr(
share::ObLocationService *location_service,
const uint64_t tenant_id,
@ -1490,11 +1523,35 @@ int ObDDLUtil::get_data_information(
uint64_t &data_format_version,
int64_t &snapshot_version,
share::ObDDLTaskStatus &task_status)
{
uint64_t target_object_id = 0;
int64_t schema_version = 0;
return get_data_information(
tenant_id,
task_id,
data_format_version,
snapshot_version,
task_status,
target_object_id,
schema_version);
}
int ObDDLUtil::get_data_information(
const uint64_t tenant_id,
const uint64_t task_id,
uint64_t &data_format_version,
int64_t &snapshot_version,
share::ObDDLTaskStatus &task_status,
uint64_t &target_object_id,
int64_t &schema_version)
{
int ret = OB_SUCCESS;
data_format_version = 0;
snapshot_version = 0;
task_status = share::ObDDLTaskStatus::PREPARE;
target_object_id = 0;
data_format_version = 0;
if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || task_id <= 0
|| nullptr == GCTX.sql_proxy_)) {
ret = OB_INVALID_ARGUMENT;
@ -1505,7 +1562,7 @@ int ObDDLUtil::get_data_information(
SMART_VAR(ObMySQLProxy::MySQLResult, res) {
ObSqlString query_string;
sqlclient::ObMySQLResult *result = NULL;
if (OB_FAIL(query_string.assign_fmt(" SELECT snapshot_version, ddl_type, UNHEX(message) as message_unhex, status FROM %s WHERE task_id = %lu",
if (OB_FAIL(query_string.assign_fmt(" SELECT snapshot_version, ddl_type, UNHEX(message) as message_unhex, status, schema_version, target_object_id FROM %s WHERE task_id = %lu",
OB_ALL_DDL_TASK_STATUS_TNAME, task_id))) {
LOG_WARN("assign sql string failed", K(ret));
} else if (OB_FAIL(GCTX.sql_proxy_->read(res, tenant_id, query_string.ptr()))) {
@ -1524,6 +1581,9 @@ int ObDDLUtil::get_data_information(
EXTRACT_INT_FIELD_MYSQL(*result, "ddl_type", ddl_type, ObDDLType);
EXTRACT_VARCHAR_FIELD_MYSQL(*result, "message_unhex", task_message);
EXTRACT_INT_FIELD_MYSQL(*result, "status", cur_task_status, int);
EXTRACT_INT_FIELD_MYSQL(*result, "target_object_id", target_object_id, int64_t);
EXTRACT_INT_FIELD_MYSQL(*result, "schema_version", schema_version, int64_t);
task_status = static_cast<share::ObDDLTaskStatus>(cur_task_status);
if (ObDDLType::DDL_CREATE_INDEX == ddl_type) {
SMART_VAR(rootserver::ObIndexBuildTask, task) {
@ -1956,6 +2016,11 @@ int ObDDLUtil::batch_check_tablet_checksum(
return ret;
}
bool ObDDLUtil::use_idempotent_mode(const int64_t data_format_version)
{
return data_format_version >= DATA_VERSION_4_3_0_1;
}
/****************** ObCheckTabletDataComplementOp *************/
int ObCheckTabletDataComplementOp::check_task_inner_sql_session_status(
@ -2786,4 +2851,4 @@ void ObDDLEventInfo::copy_event(const ObDDLEventInfo &other)
parent_trace_id_ = other.parent_trace_id_;
trace_id_ = other.trace_id_;
event_ts_ = other.event_ts_;
}
}

View File

@ -476,6 +476,9 @@ public:
const bool is_oracle_mode,
ObSqlString &sql_string);
static int generate_order_by_str_for_mview(const schema::ObTableSchema &container_table_schema,
ObSqlString &rowkey_column_sql_string);
static int ddl_get_tablet(
storage::ObLSHandle &ls_handle,
const ObTabletID &tablet_id,
@ -527,6 +530,15 @@ public:
int64_t &snapshot_version,
share::ObDDLTaskStatus &task_status);
static int get_data_information(
const uint64_t tenant_id,
const uint64_t task_id,
uint64_t &data_format_version,
int64_t &snapshot_version,
share::ObDDLTaskStatus &task_status,
uint64_t &target_object_id,
int64_t &schema_version);
static int replace_user_tenant_id(
const ObDDLType &ddl_type,
const uint64_t tenant_id,
@ -638,6 +650,7 @@ public:
}
return res;
}
static bool use_idempotent_mode(const int64_t data_format_version);
private:
static int batch_check_tablet_checksum(
@ -771,7 +784,6 @@ private:
const int64_t execution_id,
const ObIArray<ObTabletID> &tablet_ids,
bool &tablet_checksum_status);
};
typedef common::ObCurTraceId::TraceId DDLTraceId;

View File

@ -63,7 +63,7 @@ public:
}
static bool in_ddl_retry_black_list(const int ret_code)
{
return common::OB_SERVER_OUTOF_DISK_SPACE == ret_code || common::OB_DISK_ERROR == ret_code;
return common::OB_SERVER_OUTOF_DISK_SPACE == ret_code || common::OB_DISK_ERROR == ret_code || OB_NOT_SUPPORTED == ret_code;
}
static bool is_ddl_force_no_more_process(const int ret_code)
{

View File

@ -6473,8 +6473,8 @@ int ObPartitionUtils::check_param_valid_(
index_exist = true;
}
} // end for simple_index_infos
if (OB_SUCC(ret) && !finded && table_schema.has_mlog_table()) {
finded = (related_tid == table_schema.get_mlog_tid());
if (OB_SUCC(ret) && !finded && data_schema->has_mlog_table()) {
finded = (related_tid == data_schema->get_mlog_tid());
}
if (OB_SUCC(ret) && !finded && related_tid != data_table_id) {
ret = OB_TABLE_NOT_EXIST;

View File

@ -746,6 +746,44 @@ int ObSchemaUtils::alter_rowkey_column_group(share::schema::ObTableSchema &table
return ret;
}
int ObSchemaUtils::check_sys_table_exist_by_sql(
common::ObISQLClient &sql_client,
const uint64_t tenant_id,
const ObObjectID &table_id,
bool &exist)
{
int ret = OB_SUCCESS;
exist = false;
if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id)
|| OB_INVALID_ID == table_id
|| !is_sys_table(table_id)
|| is_core_table(table_id))) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid args", KR(ret), K(tenant_id), K(table_id));
} else {
SMART_VAR(ObISQLClient::ReadResult, result) {
ObSqlString sql;
common::sqlclient::ObMySQLResult *res = NULL;
// in __all_table, tenant_id is primary key and it's value is 0
if (OB_FAIL(sql.append_fmt(
"SELECT count(*) = 1 AS exist FROM %s WHERE tenant_id = 0 and table_id = %lu",
OB_ALL_TABLE_TNAME, table_id))) {
LOG_WARN("fail to assign sql", KR(ret));
} else if (OB_FAIL(sql_client.read(result, tenant_id, sql.ptr()))) {
LOG_WARN("execute sql failed", KR(ret), K(sql));
} else if (OB_ISNULL(res = result.get_result())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get mysql result failed", KR(ret), K(tenant_id), K(sql));
} else if (OB_FAIL(res->next())) {
LOG_WARN("next failed", KR(ret), K(sql));
} else if (OB_FAIL(res->get_bool("exist", exist))) {
LOG_WARN("get bool value failed", KR(ret), K(sql));
}
}
}
return ret;
}
/* check all column group add add not exi*/
int ObSchemaUtils::alter_default_column_group(share::schema::ObTableSchema &new_table_schema)
{

View File

@ -188,6 +188,21 @@ public:
const uint64_t tenant_id,
const int64_t schema_version,
const bool skip_consensus);
// Use to check if the sys table (exclude core table) does exist
// by querying __all_table when the table is not accessible.
//
// @param[in] sql_client: ObISQLClient
// @param[in] tenant_id: target tenant_id
// @param[in] table_id: sys table_id (exclude core table)
// @param[out] exist: whether the table really exists
// @return: OB_SUCCESS if success
static int check_sys_table_exist_by_sql(
common::ObISQLClient &sql_client,
const uint64_t tenant_id,
const ObObjectID &table_id,
bool &exist);
private:
static int get_tenant_variable(schema::ObSchemaGetterGuard &schema_guard,
uint64_t tenant_id,

View File

@ -378,7 +378,10 @@ public:
"rowid_mode", rowid_mode_,
"view_column_filled_flag", view_column_filled_flag_,
"mv_container_table_flag", mv_container_table_flag_,
"mv_available_flag", mv_available_flag_);
"mv_available_flag", mv_available_flag_,
"table_referenced_by_mv_flag", table_referenced_by_mv_flag_,
"mv_enable_query_rewrite_flag", mv_enable_query_rewrite_flag_,
"mv_on_query_computation_flag", mv_on_query_computation_flag_);
union {
int32_t mode_;
struct {
@ -392,6 +395,9 @@ public:
uint32_t view_column_filled_flag_ : TM_VIEW_COLUMN_FILLED_BITS;
uint32_t mv_container_table_flag_ : TM_MV_CONTAINER_TABLE_BITS;
uint32_t mv_available_flag_ : TM_MV_AVAILABLE_BITS;
uint32_t table_referenced_by_mv_flag_ : TM_TABLE_REFERENCED_BY_MV_BITS;
uint32_t mv_enable_query_rewrite_flag_ : TM_MV_ENABLE_QUERY_REWRITE_BITS;
uint32_t mv_on_query_computation_flag_ : TM_MV_ON_QUERY_COMPUTATION_BITS;
uint32_t reserved_ :TM_RESERVED;
};
};
@ -705,6 +711,18 @@ public:
{ return IS_MV_AVAILABLE == (enum ObMVAvailableFlag)table_mode_.mv_available_flag_; }
inline void set_mv_available(const ObMVAvailableFlag flag)
{ table_mode_.mv_available_flag_ = flag; }
inline bool table_referenced_by_mv() const
{ return IS_REFERENCED_BY_MV == (enum ObTableReferencedByMVFlag)table_mode_.table_referenced_by_mv_flag_; }
inline void set_table_referenced_by_mv(const ObTableReferencedByMVFlag flag)
{ table_mode_.table_referenced_by_mv_flag_ = flag; }
inline bool mv_enable_query_rewrite() const
{ return IS_MV_ENABLE_QUERY_REWRITE == (enum ObMVEnableQueryRewriteFlag)table_mode_.mv_enable_query_rewrite_flag_; }
inline void set_mv_enable_query_rewrite(const ObMVEnableQueryRewriteFlag flag)
{ table_mode_.mv_enable_query_rewrite_flag_ = flag; }
inline bool mv_on_query_computation() const
{ return IS_MV_ON_QUERY_COMPUTATION == (enum ObMVOnQueryComputationFlag)table_mode_.mv_on_query_computation_flag_; }
inline void set_mv_on_query_computation(const ObMVOnQueryComputationFlag flag)
{ table_mode_.mv_on_query_computation_flag_ = flag; }
inline void set_session_id(const uint64_t id) { session_id_ = id; }
inline uint64_t get_session_id() const { return session_id_; }

View File

@ -2727,6 +2727,77 @@ int ObTableSqlService::update_mview_status(
return ret;
}
int ObTableSqlService::update_mview_reference_table_status(
const ObTableSchema &table_schema,
common::ObISQLClient &sql_client)
{
int ret = OB_SUCCESS;
ObSqlString sql;
const uint64_t tenant_id = table_schema.get_tenant_id();
const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id);
share::schema::ObTableMode table_mode_struct = table_schema.get_table_mode_struct();
uint64_t table_id = table_schema.get_table_id();
int64_t new_schema_version = table_schema.get_schema_version();
ObDMLSqlSplicer dml;
if (OB_FAIL(dml.add_pk_column("tenant_id", ObSchemaUtils::get_extract_tenant_id(
exec_tenant_id, tenant_id)))
|| OB_FAIL(dml.add_pk_column("table_id", ObSchemaUtils::get_extract_schema_id(
exec_tenant_id, table_id)))
|| OB_FAIL(dml.add_column("schema_version", new_schema_version))
|| OB_FAIL(dml.add_column("table_mode", table_mode_struct.mode_))) {
LOG_WARN("failed to add column", KR(ret), K(exec_tenant_id), K(tenant_id));
} else {
int64_t affected_rows = 0;
const char *table_name = NULL;
if (OB_FAIL(ObSchemaUtils::get_all_table_name(exec_tenant_id, table_name))) {
LOG_WARN("fail to get all table name", KR(ret), K(exec_tenant_id));
} else if (OB_FAIL(exec_update(sql_client,
tenant_id, table_id, table_name, dml, affected_rows))) {
LOG_WARN("failed to exec update", KR(ret),
K(tenant_id), K(table_id), K(table_name));
} else if (!is_single_row(affected_rows)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected error", KR(ret), K(affected_rows));
}
}
if (OB_SUCC(ret)) {
ObRefreshSchemaStatus schema_status;
schema_status.tenant_id_ = tenant_id;
const bool update_object_status_ignore_version = false;
SMART_VAR(ObTableSchema, new_schema) {
if (OB_FAIL(schema_service_.get_table_schema_from_inner_table(
schema_status, table_id, sql_client, new_schema))) {
LOG_WARN("failed to get table schema for inner table", KR(ret), K(table_id));
} else {
const bool only_history = true;
new_schema.set_table_referenced_by_mv(ObTableMode::get_table_referenced_by_mv_flag(table_mode_struct.mode_));
new_schema.set_schema_version(new_schema_version);
new_schema.set_in_offline_ddl_white_list(table_schema.get_in_offline_ddl_white_list());
if (OB_FAIL(add_table(sql_client,
new_schema,
update_object_status_ignore_version,
only_history))) {
LOG_WARN("failed to add_table", KR(ret), K(new_schema), K(only_history));
}
}
}
}
if (OB_SUCC(ret)) {
ObSchemaOperation opt;
opt.tenant_id_ = tenant_id;
opt.database_id_ = 0;
opt.tablegroup_id_ = 0;
opt.table_id_ = table_id;
opt.op_type_ = OB_DDL_MODIFY_MVIEW_REFERENCE_TABLE_STATUS;
opt.schema_version_ = new_schema_version;
if (OB_FAIL(log_operation_wrapper(opt, sql_client))) {
LOG_WARN("log operation failed", K(ret), K(opt));
}
}
return ret;
}
int ObTableSqlService::add_transition_point_val(ObDMLSqlSplicer &dml,
const ObTableSchema &table) {

View File

@ -136,6 +136,8 @@ public:
virtual int update_mview_status(const ObTableSchema &mview_table_schema,
common::ObISQLClient &sql_client);
virtual int update_mview_reference_table_status(const ObTableSchema &table_schema,
common::ObISQLClient &sql_client);
// TODO: merge these two API
int sync_aux_schema_version_for_history(common::ObISQLClient &sql_client,
const ObTableSchema &index_schema1,

View File

@ -3709,7 +3709,7 @@ static struct VarsInit{
}();
[&] (){
ObSysVars[263].default_value_ = "1" ;
ObSysVars[263].default_value_ = "0" ;
ObSysVars[263].info_ = "Whether to enable the materialized view rewriting" ;
ObSysVars[263].name_ = "query_rewrite_enabled" ;
ObSysVars[263].data_type_ = ObIntType ;
@ -3718,7 +3718,7 @@ static struct VarsInit{
ObSysVars[263].id_ = SYS_VAR_QUERY_REWRITE_ENABLED ;
cur_max_var_id = MAX(cur_max_var_id, static_cast<int64_t>(SYS_VAR_QUERY_REWRITE_ENABLED)) ;
ObSysVarsIdToArrayIdx[SYS_VAR_QUERY_REWRITE_ENABLED] = 263 ;
ObSysVars[263].base_value_ = "1" ;
ObSysVars[263].base_value_ = "0" ;
ObSysVars[263].alias_ = "OB_SV_QUERY_REWRITE_ENABLED" ;
}();

View File

@ -3760,8 +3760,8 @@
"query_rewrite_enabled": {
"id": 10179,
"name": "query_rewrite_enabled",
"default_value": "1",
"base_value": "1",
"default_value": "0",
"base_value": "0",
"data_type": "enum",
"info": "Whether to enable the materialized view rewriting",
"flags": "GLOBAL | SESSION | NEED_SERIALIZE | INFLUENCE_PLAN",

View File

@ -19,36 +19,36 @@ namespace oceanbase
namespace table
{
OB_SERIALIZE_MEMBER_SIMPLE(ObTableLoadConfig,
parallel_,
batch_size_,
max_error_row_count_,
dup_action_,
is_need_sort_);
OB_SERIALIZE_MEMBER(ObTableLoadConfig,
parallel_,
batch_size_,
max_error_row_count_,
dup_action_,
is_need_sort_);
OB_SERIALIZE_MEMBER_SIMPLE(ObTableLoadSegmentID,
id_);
OB_SERIALIZE_MEMBER(ObTableLoadSegmentID,
id_);
OB_SERIALIZE_MEMBER_SIMPLE(ObTableLoadTransId,
segment_id_,
trans_gid_);
OB_SERIALIZE_MEMBER(ObTableLoadTransId,
segment_id_,
trans_gid_);
OB_SERIALIZE_MEMBER_SIMPLE(ObTableLoadPartitionId,
partition_id_,
tablet_id_);
OB_SERIALIZE_MEMBER(ObTableLoadPartitionId,
partition_id_,
tablet_id_);
OB_SERIALIZE_MEMBER_SIMPLE(ObTableLoadLSIdAndPartitionId,
ls_id_,
part_tablet_id_);
OB_SERIALIZE_MEMBER(ObTableLoadLSIdAndPartitionId,
ls_id_,
part_tablet_id_);
OB_SERIALIZE_MEMBER_SIMPLE(ObTableLoadResultInfo,
rows_affected_,
records_,
deleted_,
skipped_,
warnings_);
OB_SERIALIZE_MEMBER(ObTableLoadResultInfo,
rows_affected_,
records_,
deleted_,
skipped_,
warnings_);
OB_SERIALIZE_MEMBER_SIMPLE(ObTableLoadSequenceNo, sequence_no_);
OB_SERIALIZE_MEMBER(ObTableLoadSequenceNo, sequence_no_);
} // namespace table
} // namespace oceanbase

View File

@ -33,6 +33,7 @@ ob_set_subtarget(ob_sql common_mixed
resolver/mv/ob_mv_checker.cpp
resolver/mv/ob_mv_provider.cpp
resolver/mv/ob_mv_printer.cpp
resolver/mv/ob_mv_dep_utils.cpp
)
ob_set_subtarget(ob_sql das
@ -719,6 +720,7 @@ ob_set_subtarget(ob_sql engine_expr
engine/expr/ob_expr_extract_cert_expired_time.cpp
engine/expr/ob_expr_transaction_id.cpp
engine/expr/ob_expr_inner_row_cmp_val.cpp
engine/expr/ob_expr_last_refresh_scn.cpp
engine/expr/ob_expr_json_utils.cpp
)
@ -1282,6 +1284,7 @@ ob_set_subtarget(ob_sql rewrite
rewrite/ob_transform_expr_pullup.cpp
rewrite/ob_transformer_impl.cpp
rewrite/ob_transform_dblink.cpp
rewrite/ob_transform_mv_rewrite.cpp
rewrite/ob_union_find.cpp
rewrite/ob_transform_decorrelate.cpp
)

View File

@ -1508,14 +1508,20 @@ int ObDmlCgService::check_upd_need_all_columns(ObLogDelUpd &op,
need_all_columns = false;
int64_t binlog_row_image = ObBinlogRowImage::FULL;
ObSQLSessionInfo *session = cg_.opt_ctx_->get_session_info();
if (OB_ISNULL(session)) {
if (OB_ISNULL(session) || OB_ISNULL(schema_guard) || OB_ISNULL(table_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null ptr", K(ret));
LOG_WARN("unexpected null ptr", K(ret), KP(session), KP(schema_guard), KP(table_schema));
} else if (OB_FAIL(session->get_binlog_row_image(binlog_row_image))) {
LOG_WARN("fail to get binlog image", K(ret));
} else if (binlog_row_image == ObBinlogRowImage::FULL || op.has_instead_of_trigger()) {
// full mode
need_all_columns = true;
} else if (table_schema->has_mlog_table()) {
need_all_columns = true;
LOG_TRACE("update table with materialized view log, need all columns", K(table_schema->has_mlog_table()));
} else if (table_schema->is_mlog_table()) {
need_all_columns = true;
LOG_TRACE("update materialized view log, need all columns", K(table_schema->is_mlog_table()));
} else if (!is_primary_index) {
// index_table if update PK, also need record all_columns
if (OB_FAIL(check_has_upd_rowkey(op, table_schema, index_dml_info, is_update_pk))) {
@ -1658,14 +1664,20 @@ int ObDmlCgService::check_del_need_all_columns(ObLogDelUpd &op,
bool has_not_null_uk = false;
int64_t binlog_row_image = ObBinlogRowImage::FULL;
ObSQLSessionInfo *session = cg_.opt_ctx_->get_session_info();
if (OB_ISNULL(session)) {
if (OB_ISNULL(session) || OB_ISNULL(schema_guard) || OB_ISNULL(table_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null ptr", K(ret));
LOG_WARN("unexpected null ptr", K(ret), KP(session), KP(schema_guard), KP(table_schema));
} else if (OB_FAIL(session->get_binlog_row_image(binlog_row_image))) {
LOG_WARN("fail to get binlog image", K(ret));
} else if (binlog_row_image == ObBinlogRowImage::FULL || op.has_instead_of_trigger()) {
// full mode
need_all_columns = true;
} else if (table_schema->has_mlog_table()) {
need_all_columns = true;
LOG_TRACE("delete from table with materialized view log, need all columns", K(table_schema->has_mlog_table()));
} else if (table_schema->is_mlog_table()) {
need_all_columns = true;
LOG_TRACE("delete from materialized view log, need all columns", K(table_schema->is_mlog_table()));
} else if (table_schema->is_heap_table()) {
if (OB_FAIL(table_schema->has_not_null_unique_key(*schema_guard, has_not_null_uk))) {
LOG_WARN("fail to check whether has not null unique key", K(ret), K(table_schema->get_table_name_str()));

View File

@ -843,6 +843,11 @@ int ObStaticEngineCG::generate_spec_basic(ObLogicalOperator &op,
if (OB_SUCC(ret) && need_check_output_datum) {
OZ(add_output_datum_check_flag(spec));
}
if (OB_SUCC(ret)) {
if (OB_FAIL(extract_all_mview_ids(cur_op_exprs_))) {
LOG_WARN("fail to extract all mview ids", K(ret));
}
}
if (OB_SUCC(ret)) {
CK (OB_NOT_NULL(op.get_plan())
&& OB_NOT_NULL(op.get_plan()->get_stmt())
@ -862,6 +867,37 @@ int ObStaticEngineCG::generate_spec_basic(ObLogicalOperator &op,
return ret;
}
int ObStaticEngineCG::extract_all_mview_ids(const ObIArray<ObRawExpr *> &exprs)
{
int ret = OB_SUCCESS;
for (int i = 0; OB_SUCC(ret) && i < exprs.count(); ++i) {
if (OB_FAIL(extract_all_mview_ids(exprs.at(i)))) {
LOG_WARN("extract all mview ids failed", K(ret), K(i), KPC(exprs.at(i)));
}
}
return ret;
}
int ObStaticEngineCG::extract_all_mview_ids(const ObRawExpr *expr)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("expr is null", K(ret), K(expr));
} else if (ObItemType::T_FUN_SYS_LAST_REFRESH_SCN == expr->get_expr_type()) {
if (OB_FAIL(add_var_to_array_no_dup(mview_ids_, static_cast<const ObSysFunRawExpr*>(expr)->get_mview_id()))) {
LOG_WARN("failed to add var to array no dup", K(ret), K(mview_ids_.count()));
}
} else {
for (int i = 0; OB_SUCC(ret) && i < expr->get_param_count(); ++i) {
if (OB_FAIL(SMART_CALL(extract_all_mview_ids(expr->get_param_expr(i))))) {
LOG_WARN("extract all mview ids failed", K(ret), KPC(expr->get_param_expr(i)));
}
}
}
return ret;
}
int ObStaticEngineCG::generate_calc_exprs(
const ObIArray<ObRawExpr *> &dep_exprs,
const ObIArray<ObRawExpr *> &cur_exprs,
@ -7883,6 +7919,8 @@ int ObStaticEngineCG::set_other_properties(const ObLogPlan &log_plan, ObPhysical
LOG_WARN("set expected worker map", K(ret));
} else if (OB_FAIL(phy_plan.set_minimal_worker_map(log_plan.get_optimizer_context().get_minimal_worker_map()))) {
LOG_WARN("set minimal worker map", K(ret));
} else if (OB_FAIL(phy_plan.set_mview_ids(mview_ids_))) {
LOG_WARN("failed to set set mview_ids", K(ret), K(mview_ids_.count()));
} else {
if (log_plan.get_optimizer_context().is_online_ddl()) {
if (log_plan.get_stmt()->get_table_items().count() > 0) {
@ -7900,6 +7938,17 @@ int ObStaticEngineCG::set_other_properties(const ObLogPlan &log_plan, ObPhysical
}
}
}
if (log_plan.get_optimizer_context().get_session_info()->get_ddl_info().is_mview_complete_refresh()) {
if (log_plan.get_stmt()->get_table_items().count() > 0) {
const TableItem *insert_table_item = log_plan.get_stmt()->get_table_item(0);
if (nullptr != insert_table_item) {
int64_t ddl_task_id = 0;
const ObOptParamHint *opt_params = &log_plan.get_stmt()->get_query_ctx()->get_global_hint().opt_params_;
OZ(opt_params->get_integer_opt_param(ObOptParamHint::DDL_TASK_ID, ddl_task_id));
log_plan.get_optimizer_context().get_exec_ctx()->get_table_direct_insert_ctx().set_ddl_task_id(ddl_task_id);
}
}
}
}
ObParamOption param_opt = log_plan.get_optimizer_context().get_global_hint().param_option_;
bool is_exact_mode = my_session->get_enable_exact_mode();

View File

@ -558,6 +558,8 @@ private:
int generate_sort_exprs(const bool is_store_sortkey_separately, ObLogSort &op, ObSortVecSpec &spec,
ObIArray<OrderItem> &sk_keys);
int extract_all_mview_ids(const ObIArray<ObRawExpr *> &exprs);
int extract_all_mview_ids(const ObRawExpr *expr);
private:
struct BatchExecParamCache {
BatchExecParamCache(ObExecParamRawExpr* expr, ObOpSpec* spec, bool is_left)
@ -594,6 +596,7 @@ private:
ObTscCgService tsc_cg_service_;
uint64_t cur_cluster_version_;
common::ObSEArray<BatchExecParamCache, 8> batch_exec_param_caches_;
common::ObSEArray<uint64_t, 4> mview_ids_;
};

View File

@ -482,18 +482,17 @@ int ObDASUtils::generate_mlog_row(const ObTabletID &tablet_id,
} else if (OB_FAIL(auto_inc.get_autoinc_seq(tenant_id, tablet_id, autoinc_seq))) {
LOG_WARN("get_autoinc_seq fail", K(ret), K(tenant_id), K(tablet_id));
} else {
// sequence_col is the first primary key
// mlog_row = | base_table_rowkey_cols | partition key cols | sequence_col | ... | dmltype_col | old_new_col |
int sequence_col = 0;
int dmltype_col = row.count_ - 2;
int old_new_col = row.count_ - 1;
const ObTableDMLParam::ObColDescArray &col_descs = dml_param.table_param_->get_col_descs();
bool is_heap_base_table = (OB_MLOG_ROWID_COLUMN_ID == col_descs.at(row.count_ - 1).col_id_);
// if the base table is heap table, then the last column is mlog_rowid,
// therefore, row = | sequence_col | partition key cols | ... | dmltype_col | old_new_col | rowid_col |
// otherwise, row = | sequence_col | partition key cols | ... | dmltype_col | old_new_col |
if (is_heap_base_table) {
dmltype_col = dmltype_col - 1;
old_new_col = old_new_col - 1;
bool found_seq_col = false;
for (int64_t i = 0; !found_seq_col && (i < row.count_); ++i) {
if (OB_MLOG_SEQ_NO_COLUMN_ID == col_descs.at(i).col_id_) {
sequence_col = i; // sequence_no is the last rowkey
found_seq_col = true;
}
}
row.cells_[sequence_col].set_int(ObObjType::ObIntType, static_cast<int64_t>(autoinc_seq));

View File

@ -48,6 +48,7 @@ int ObDDLExecutorUtil::handle_session_exception(ObSQLSessionInfo &session)
int ObDDLExecutorUtil::wait_ddl_finish(
const uint64_t tenant_id,
const int64_t task_id,
const bool ddl_need_retry_at_executor,
ObSQLSessionInfo *session,
obrpc::ObCommonRpcProxy *common_rpc_proxy,
const bool is_support_cancel)
@ -79,7 +80,12 @@ int ObDDLExecutorUtil::wait_ddl_finish(
tenant_id, task_id, -1 /* target_object_id */, unused_addr, false /* is_ddl_retry_task */, *GCTX.sql_proxy_, error_message, unused_user_msg_len)) {
ret = error_message.ret_code_;
if (OB_SUCCESS != ret) {
FORWARD_USER_ERROR(ret, error_message.user_message_);
if (ddl_need_retry_at_executor) {
ret = ObIDDLTask::in_ddl_retry_white_list(ret) ? OB_EAGAIN : ret;
LOG_WARN("is ddl need retry at user", K(ret));
} else {
FORWARD_USER_ERROR(ret, error_message.user_message_);
}
}
break;
} else {

View File

@ -55,6 +55,7 @@ public:
static int wait_ddl_finish(
const uint64_t tenant_id,
const int64_t task_id,
const bool ddl_need_retry_at_executor,
ObSQLSessionInfo *session,
obrpc::ObCommonRpcProxy *common_rpc_proxy,
const bool is_support_cancel = true);

View File

@ -99,7 +99,7 @@ int ObCreateIndexExecutor::execute(ObExecContext &ctx, ObCreateIndexStmt &stmt)
ret = OB_ERR_ADD_INDEX;
LOG_WARN("index table id is invalid", KR(ret));
}
} else if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(create_index_arg.tenant_id_, res.task_id_, my_session, common_rpc_proxy))) {
} else if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(create_index_arg.tenant_id_, res.task_id_, false/*do not need retry at executor*/, my_session, common_rpc_proxy))) {
LOG_WARN("failed to wait ddl finish", K(ret));
}
}

View File

@ -31,6 +31,7 @@ namespace sql
using namespace common;
using namespace observer;
using namespace share;
using namespace storage;
using namespace table;
using namespace omt;
@ -2042,6 +2043,8 @@ int ObLoadDataDirectImpl::init_execute_context()
load_param.sql_mode_ = execute_param_.sql_mode_;
load_param.px_mode_ = false;
load_param.online_opt_stat_gather_ = execute_param_.online_opt_stat_gather_;
load_param.method_ = ObDirectLoadMethod::FULL;
load_param.insert_mode_ = ObDirectLoadInsertMode::NORMAL;
if (OB_FAIL(direct_loader_.init(load_param, execute_param_.store_column_idxs_,
&execute_ctx_.exec_ctx_))) {
LOG_WARN("fail to init direct loader", KR(ret));

View File

@ -75,7 +75,7 @@ int ObCreateMLogExecutor::execute(ObExecContext &ctx, ObCreateMLogStmt &stmt)
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected schema version", KR(ret), K(create_mlog_res));
} else if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(create_mlog_arg.tenant_id_,
create_mlog_res.task_id_, my_session, common_rpc_proxy))) {
create_mlog_res.task_id_, false/*do not need retry at executor*/, my_session, common_rpc_proxy))) {
LOG_WARN("failed to wait ddl finish", KR(ret));
}
}

View File

@ -55,15 +55,12 @@ int ObTableDirectInsertCtx::init(ObExecContext *exec_ctx,
LOG_WARN("fail to new ObTableLoadInstance", KR(ret));
} else {
load_exec_ctx_->exec_ctx_ = exec_ctx;
uint64_t sql_mode = 0;
ObSEArray<int64_t, 16> store_column_idxs;
omt::ObTenant *tenant = nullptr;
if (OB_FAIL(GCTX.omt_->get_tenant(MTL_ID(), tenant))) {
LOG_WARN("fail to get tenant handle", KR(ret), K(MTL_ID()));
} else if (OB_FAIL(init_store_column_idxs(MTL_ID(), table_id, store_column_idxs))) {
LOG_WARN("failed to init store column idxs", KR(ret));
} else if (OB_FAIL(exec_ctx->get_my_session()->get_sys_variable(SYS_VAR_SQL_MODE, sql_mode))) {
LOG_WARN("fail to get sys variable", KR(ret));
} else {
ObTableLoadParam param;
param.column_count_ = store_column_idxs.count();
@ -77,8 +74,11 @@ int ObTableDirectInsertCtx::init(ObExecContext *exec_ctx,
param.need_sort_ = true;
param.max_error_row_count_ = 0;
param.dup_action_ = sql::ObLoadDupActionType::LOAD_STOP_ON_DUP;
param.sql_mode_ = sql_mode;
param.online_opt_stat_gather_ = is_online_gather_statistics_;
param.method_ = ObDirectLoadMethod::FULL;
param.insert_mode_ = (exec_ctx->get_my_session()->get_ddl_info().is_mview_complete_refresh()
? ObDirectLoadInsertMode::OVERWRITE
: ObDirectLoadInsertMode::NORMAL);
if (OB_FAIL(table_load_instance_->init(param, store_column_idxs, load_exec_ctx_))) {
LOG_WARN("failed to init direct loader", KR(ret));
} else {

View File

@ -34,7 +34,8 @@ public:
table_load_instance_(nullptr),
is_inited_(false),
is_direct_(false),
is_online_gather_statistics_(false) {}
is_online_gather_statistics_(false),
ddl_task_id_(0) {}
~ObTableDirectInsertCtx();
TO_STRING_KV(K_(is_inited));
public:
@ -53,6 +54,14 @@ public:
is_online_gather_statistics_ = is_online_gather_statistics;
}
void set_ddl_task_id(const int64_t ddl_task_id) {
ddl_task_id_ = ddl_task_id;
}
int64_t get_ddl_task_id() const {
return ddl_task_id_;
}
private:
int init_store_column_idxs(const uint64_t tenant_id, const uint64_t table_id,
common::ObIArray<int64_t> &store_column_idxs);
@ -62,6 +71,7 @@ private:
bool is_inited_;
bool is_direct_; //indict whether the plan is direct load plan including insert into append and load data direct
bool is_online_gather_statistics_;
int64_t ddl_task_id_;
};
} // namespace observer
} // namespace oceanbase

View File

@ -625,7 +625,7 @@ int ObCreateTableExecutor::execute(ObExecContext &ctx, ObCreateTableStmt &stmt)
ret = OB_ERR_UNEXPECTED;
LOG_WARN("session_info should not be nullptr", KR(ret));
} else if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(
tenant_id, res.task_id_, session_info, common_rpc_proxy, true))) {
tenant_id, res.task_id_, false/*do not retry at executor*/, session_info, common_rpc_proxy, true))) {
if (storage::ObMViewExecutorUtil::is_mview_refresh_retry_ret_code(ret)) {
LOG_WARN("retry create mview", KR(ret), K(tenant_id), "task_id", res.task_id_);
ret = OB_EAGAIN;
@ -813,7 +813,7 @@ int ObAlterTableExecutor::alter_table_rpc_v2(
ObIArray<obrpc::ObDDLRes> &ddl_ress = res.ddl_res_array_;
for (int64_t i = 0; OB_SUCC(ret) && i < ddl_ress.count(); ++i) {
ObDDLRes &ddl_res = ddl_ress.at(i);
if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(ddl_res.tenant_id_, ddl_res.task_id_, my_session, common_rpc_proxy, is_support_cancel))) {
if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(ddl_res.tenant_id_, ddl_res.task_id_, false/*do not retry at executor*/, my_session, common_rpc_proxy, is_support_cancel))) {
LOG_WARN("wait drop index finish", K(ret));
}
}
@ -1142,7 +1142,7 @@ int ObAlterTableExecutor::execute(ObExecContext &ctx, ObAlterTableStmt &stmt)
// do nothing, don't check if data is valid
} else if (OB_FAIL(refresh_schema_for_table(tenant_id))) {
LOG_WARN("refresh_schema_for_table failed", K(ret));
} else if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(tenant_id, res.task_id_, my_session, common_rpc_proxy))) {
} else if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(tenant_id, res.task_id_, res.ddl_need_retry_at_executor_, my_session, common_rpc_proxy))) {
LOG_WARN("wait check constraint finish", K(ret));
}
}
@ -1153,7 +1153,7 @@ int ObAlterTableExecutor::execute(ObExecContext &ctx, ObAlterTableStmt &stmt)
} else {
if (OB_FAIL(refresh_schema_for_table(tenant_id))) {
LOG_WARN("refresh_schema_for_table failed", K(ret));
} else if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(tenant_id, res.task_id_, my_session, common_rpc_proxy))) {
} else if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(tenant_id, res.task_id_, res.ddl_need_retry_at_executor_, my_session, common_rpc_proxy))) {
LOG_WARN("wait fk constraint finish", K(ret));
}
}
@ -1166,7 +1166,7 @@ int ObAlterTableExecutor::execute(ObExecContext &ctx, ObAlterTableStmt &stmt)
int64_t affected_rows = 0;
if (OB_FAIL(refresh_schema_for_table(alter_table_arg.exec_tenant_id_))) {
LOG_WARN("refresh_schema_for_table failed", K(ret));
} else if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(tenant_id, res.task_id_, my_session, common_rpc_proxy))) {
} else if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(tenant_id, res.task_id_, res.ddl_need_retry_at_executor_, my_session, common_rpc_proxy))) {
LOG_WARN("fail to wait ddl finish", K(ret), K(tenant_id), K(res));
}
}

View File

@ -347,6 +347,7 @@
#include "ob_expr_extract_cert_expired_time.h"
#include "ob_expr_transaction_id.h"
#include "ob_expr_inner_row_cmp_val.h"
#include "ob_expr_last_refresh_scn.h"
#include "ob_expr_sql_udt_construct.h"
#include "ob_expr_priv_attribute_access.h"
#include "ob_expr_temp_table_ssid.h"
@ -1160,7 +1161,7 @@ static ObExpr::EvalFunc g_expr_eval_functions[] = {
NULL, // ObExprGTIDSubtract::eval_subtract, /* 687 */
NULL, // ObExprWaitForExecutedGTIDSet::eval_wait_for_executed_gtid_set, /* 688 */
NULL, // ObExprWaitUntilSQLThreadAfterGTIDs::eval_wait_until_sql_thread_after_gtids /* 689 */
NULL, // ObExprLastRefreshScn::eval_last_refresh_scn /* 690 */
ObExprLastRefreshScn::eval_last_refresh_scn, /* 690 */
NULL, // ObExprDocLength::generate_doc_length, /*691*/
NULL, // ObExprTopNFilter::eval_topn_filter, /* 692 */
NULL, // ObExprIsEnabledRole::eval_is_enabled_role, /* 693 */

View File

@ -33,6 +33,7 @@
#include "sql/engine/expr/ob_expr_sql_udt_construct.h"
#include "sql/engine/expr/ob_expr_priv_attribute_access.h"
#include "sql/engine/expr/ob_expr_lrpad.h"
#include "sql/engine/expr/ob_expr_last_refresh_scn.h"
#include "sql/engine/expr/ob_expr_json_schema_valid.h"
#include "sql/engine/expr/ob_expr_json_schema_validation_report.h"
#include "sql/engine/expr/ob_expr_json_utils.h"
@ -108,6 +109,7 @@ void ObExprExtraInfoFactory::register_expr_extra_infos()
REG_EXTRA_INFO(T_FUN_SYS_PRIV_SQL_UDT_ATTR_ACCESS, ObExprUdtAttrAccessInfo);
REG_EXTRA_INFO(T_FUN_SYS_LPAD, ObExprOracleLRpadInfo);
REG_EXTRA_INFO(T_FUN_SYS_RPAD, ObExprOracleLRpadInfo);
REG_EXTRA_INFO(T_FUN_SYS_LAST_REFRESH_SCN, ObExprLastRefreshScn::LastRefreshScnExtraInfo);
REG_EXTRA_INFO(T_FUN_SYS_JSON_SCHEMA_VALID, ObExprJsonSchemaValidInfo);
REG_EXTRA_INFO(T_FUN_SYS_JSON_SCHEMA_VALIDATION_REPORT, ObExprJsonSchemaValidInfo);
REG_EXTRA_INFO(T_FUN_SYS_JSON_VALUE, ObExprJsonQueryParamInfo);

View File

@ -0,0 +1,202 @@
/**
* 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/expr/ob_expr_last_refresh_scn.h"
#include "sql/engine/expr/ob_expr_util.h"
#include "sql/engine/ob_physical_plan_ctx.h"
#include "sql/engine/ob_exec_context.h"
namespace oceanbase
{
using namespace common;
namespace sql
{
ObExprLastRefreshScn::ObExprLastRefreshScn(ObIAllocator &alloc)
: ObFuncExprOperator(alloc, T_FUN_SYS_LAST_REFRESH_SCN, N_SYS_LAST_REFRESH_SCN, 0, NOT_VALID_FOR_GENERATED_COL, NOT_ROW_DIMENSION)
{
}
ObExprLastRefreshScn::~ObExprLastRefreshScn()
{
}
int ObExprLastRefreshScn::calc_result_type0(ObExprResType &type, ObExprTypeCtx &type_ctx) const
{
UNUSED(type_ctx);
if (is_oracle_mode()) {
const ObAccuracy &acc = ObAccuracy::DDL_DEFAULT_ACCURACY2[common::ORACLE_MODE][common::ObNumberType];
type.set_number();
type.set_scale(acc.get_scale());
type.set_precision(acc.get_precision());
} else {
const ObAccuracy &acc = common::ObAccuracy::DDL_DEFAULT_ACCURACY[common::ObUInt64Type];
type.set_uint64();
type.set_scale(acc.get_scale());
type.set_precision(acc.get_precision());
type.set_result_flag(NOT_NULL_FLAG);
}
return OB_SUCCESS;
}
int ObExprLastRefreshScn::eval_last_refresh_scn(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum)
{
int ret = OB_SUCCESS;
uint64_t scn = OB_INVALID_SCN_VAL;
const ObExprLastRefreshScn::LastRefreshScnExtraInfo *info =
static_cast<const ObExprLastRefreshScn::LastRefreshScnExtraInfo*>(expr.extra_info_);
const ObPhysicalPlanCtx *phy_plan_ctx = NULL;
if (OB_ISNULL(info) || OB_ISNULL(phy_plan_ctx = ctx.exec_ctx_.get_physical_plan_ctx())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("phy_plan_ctx is null", K(ret), K(info), K(phy_plan_ctx));
} else if (OB_UNLIKELY(OB_INVALID_SCN_VAL == (scn = phy_plan_ctx->get_last_refresh_scn(info->mview_id_)))) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("failed to get valid last_refresh_scn for mview id", K(ret), K(info->mview_id_), K(lbt()));
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "materialized view id in last_refresh_scn");
} else if (ObUInt64Type == expr.datum_meta_.type_) {
expr_datum.set_uint(scn);
} else {
ObNumStackOnceAlloc tmp_alloc;
number::ObNumber num;
if (OB_FAIL(num.from(scn, tmp_alloc))) {
LOG_WARN("copy number fail", K(ret));
} else {
expr_datum.set_number(num);
}
}
return ret;
}
int ObExprLastRefreshScn::cg_expr(ObExprCGCtx &op_cg_ctx, const ObRawExpr &raw_expr, ObExpr &rt_expr) const
{
int ret = OB_SUCCESS;
LastRefreshScnExtraInfo *extra_info = NULL;
void *buf = NULL;
if (OB_ISNULL(op_cg_ctx.allocator_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("allocator is null", K(ret));
} else if (OB_ISNULL(buf = op_cg_ctx.allocator_->alloc(sizeof(LastRefreshScnExtraInfo)))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc memory", K(ret));
} else {
extra_info = new(buf) LastRefreshScnExtraInfo(*op_cg_ctx.allocator_, type_);
extra_info->mview_id_ = static_cast<const ObSysFunRawExpr&>(raw_expr).get_mview_id();
rt_expr.eval_func_ = ObExprLastRefreshScn::eval_last_refresh_scn;
rt_expr.extra_info_ = extra_info;
}
return OB_SUCCESS;
}
OB_SERIALIZE_MEMBER(ObExprLastRefreshScn::LastRefreshScnExtraInfo, mview_id_);
int ObExprLastRefreshScn::LastRefreshScnExtraInfo::deep_copy(common::ObIAllocator &allocator,
const ObExprOperatorType type,
ObIExprExtraInfo *&copied_info) const
{
int ret = OB_SUCCESS;
OZ(ObExprExtraInfoFactory::alloc(allocator, type, copied_info));
LastRefreshScnExtraInfo &other = *static_cast<LastRefreshScnExtraInfo *>(copied_info);
if (OB_SUCC(ret)) {
other = *this;
}
return ret;
}
int ObExprLastRefreshScn::set_last_refresh_scns(const ObIArray<uint64_t> &src_mview_ids,
ObMySQLProxy *sql_proxy,
ObSQLSessionInfo *session,
const share::SCN &scn,
ObIArray<uint64_t> &mview_ids,
ObIArray<uint64_t> &last_refresh_scns)
{
int ret = OB_SUCCESS;
mview_ids.reuse();
last_refresh_scns.reuse();
ObSEArray<uint64_t, 2> res_ids;
ObSEArray<uint64_t, 2> res_scns;
if (OB_ISNULL(sql_proxy) || OB_ISNULL(session)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret));
} else {
SMART_VAR(ObMySQLProxy::MySQLResult, res) {
ObSqlString sql;
sqlclient::ObMySQLResult *mysql_result = NULL;
if (OB_FAIL(get_last_refresh_scn_sql(scn, src_mview_ids, sql))) {
LOG_WARN("failed to get last refresh scn sql", K(ret));
} else if (OB_FAIL(sql_proxy->read(res, session->get_effective_tenant_id(), sql.ptr()))) {
LOG_WARN("execute sql failed", K(ret), K(sql));
} else if (OB_ISNULL(mysql_result = res.get_result())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("execute sql fail", K(ret));
} else {
ObSEArray<uint64_t, 2> res_ids;
ObSEArray<uint64_t, 2> res_scns;
const int64_t col_idx0 = 0;
const int64_t col_idx1 = 1;
while (OB_SUCC(ret) && OB_SUCC(mysql_result->next())) {
int64_t mview_id = OB_INVALID_ID;
uint64_t last_refresh_scn = OB_INVALID_SCN_VAL;
if (OB_FAIL(mysql_result->get_int(col_idx0, mview_id))
|| OB_FAIL(mysql_result->get_uint(col_idx1, last_refresh_scn))) {
LOG_WARN("fail to get int/uint value", K(ret));
} else if (OB_FAIL(res_ids.push_back(mview_id))
|| OB_FAIL(res_scns.push_back(last_refresh_scn))) {
LOG_WARN("fail to push back", K(ret));
}
}
if (OB_UNLIKELY(OB_SUCCESS == ret || OB_ITER_END == ret)
&& (OB_FAIL(mview_ids.assign(res_ids)) || OB_FAIL(last_refresh_scns.assign(res_scns)))) {
LOG_WARN("fail to assign array", K(ret));
}
}
}
}
return ret;
}
int ObExprLastRefreshScn::get_last_refresh_scn_sql(const share::SCN &scn,
const ObIArray<uint64_t> &mview_ids,
ObSqlString &sql)
{
int ret = OB_SUCCESS;
ObSqlString mview_id_array;
if (OB_UNLIKELY(mview_ids.empty())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpect empty array", K(ret), K(mview_ids));
} else if (OB_UNLIKELY(mview_ids.count() > 100)) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("more than 100 different materialized view id used in last_refresh_scn", K(ret), K(mview_ids.count()));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "more than 100 different materialized view id used in last_refresh_scn is");
} else {
for (int i = 0; OB_SUCC(ret) && i < mview_ids.count(); ++i) {
if (OB_FAIL(mview_id_array.append_fmt(0 == i ? "%ld" : ",%ld", mview_ids.at(i)))) {
LOG_WARN("fail to append fmt", KR(ret));
}
}
}
if (OB_FAIL(ret)) {
} else if (SCN::invalid_scn() == scn) {
if (OB_FAIL(sql.assign_fmt("SELECT MVIEW_ID, LAST_REFRESH_SCN FROM `%s`.`%s` WHERE TENANT_ID = 0 AND MVIEW_ID IN (%.*s)",
OB_SYS_DATABASE_NAME, OB_ALL_MVIEW_TNAME,
(int)mview_id_array.length(), mview_id_array.ptr()))) {
LOG_WARN("fail to assign sql", KR(ret));
}
} else if (OB_FAIL(sql.assign_fmt("SELECT MVIEW_ID, LAST_REFRESH_SCN FROM `%s`.`%s` AS OF SNAPSHOT %ld WHERE TENANT_ID = 0 AND MVIEW_ID IN (%.*s)",
OB_SYS_DATABASE_NAME, OB_ALL_MVIEW_TNAME, scn.get_val_for_sql(),
(int)mview_id_array.length(), mview_id_array.ptr()))) {
LOG_WARN("fail to assign sql", KR(ret), K(scn));
}
return ret;
}
} //namespace sql
} //namespace oceanbase

View File

@ -0,0 +1,67 @@
/**
* 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_EXPR_LAST_REFRESH_SCN_H_
#define OCEANBASE_SQL_OB_EXPR_LAST_REFRESH_SCN_H_
#include "sql/engine/expr/ob_expr_operator.h"
namespace oceanbase
{
namespace sql
{
class ObExprLastRefreshScn : public ObFuncExprOperator
{
public:
explicit ObExprLastRefreshScn(common::ObIAllocator &alloc);
virtual ~ObExprLastRefreshScn();
struct LastRefreshScnExtraInfo : public ObIExprExtraInfo
{
OB_UNIS_VERSION(1);
public:
LastRefreshScnExtraInfo(common::ObIAllocator &alloc, ObExprOperatorType type)
: ObIExprExtraInfo(alloc, type),
mview_id_(share::OB_INVALID_SCN_VAL)
{
}
virtual ~LastRefreshScnExtraInfo() { }
virtual int deep_copy(common::ObIAllocator &allocator,
const ObExprOperatorType type,
ObIExprExtraInfo *&copied_info) const override;
uint64_t mview_id_;
};
virtual int calc_result_type0(ObExprResType &type, common::ObExprTypeCtx &type_ctx) const;
static int eval_last_refresh_scn(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum);
virtual int cg_expr(ObExprCGCtx &op_cg_ctx,
const ObRawExpr &raw_expr,
ObExpr &rt_expr) const override;
static int set_last_refresh_scns(const ObIArray<uint64_t> &src_mview_ids,
ObMySQLProxy *sql_proxy,
ObSQLSessionInfo *session,
const share::SCN &scn,
ObIArray<uint64_t> &mview_ids,
ObIArray<uint64_t> &last_refresh_scns);
static int get_last_refresh_scn_sql(const share::SCN &scn,
const ObIArray<uint64_t> &mview_ids,
ObSqlString &sql);
private:
// disallow copy
DISALLOW_COPY_AND_ASSIGN(ObExprLastRefreshScn);
};
} //sql
} //oceanbase
#endif //OCEANBASE_SQL_OB_EXPR_CURRENT_SCN_H_

View File

@ -418,6 +418,7 @@
#include "sql/engine/expr/ob_expr_extract_cert_expired_time.h"
#include "sql/engine/expr/ob_expr_transaction_id.h"
#include "sql/engine/expr/ob_expr_inner_row_cmp_val.h"
#include "sql/engine/expr/ob_expr_last_refresh_scn.h"
#include "sql/engine/expr/ob_expr_priv_st_makeenvelope.h"
#include "sql/engine/expr/ob_expr_priv_st_clipbybox2d.h"
#include "sql/engine/expr/ob_expr_priv_st_pointonsurface.h"
@ -1048,6 +1049,7 @@ void ObExprOperatorFactory::register_expr_operators()
REG_OP(ObExprExtractExpiredTime);
REG_OP(ObExprTransactionId);
REG_OP(ObExprInnerRowCmpVal);
REG_OP(ObExprLastRefreshScn);
// REG_OP(ObExprTopNFilter);
REG_OP(ObExprPrivSTMakeEnvelope);
REG_OP(ObExprPrivSTClipByBox2D);
@ -1382,6 +1384,7 @@ void ObExprOperatorFactory::register_expr_operators()
REG_OP_ORCL(ObExprJsonObjectStar);
REG_OP_ORCL(ObExprTransactionId);
REG_OP_ORCL(ObExprInnerRowCmpVal);
REG_OP_ORCL(ObExprLastRefreshScn);
// REG_OP_ORCL(ObExprTopNFilter);
}

View File

@ -512,6 +512,8 @@ public:
const ObSubSchemaCtx &get_subschema_ctx() const { return subschema_ctx_; }
int set_all_local_session_vars(ObIArray<ObLocalSessionVar> *all_local_session_vars);
ObIArray<ObLocalSessionVar> & get_all_local_session_vars() { return all_local_session_vars_; }
inline const ObIArray<uint64_t> &get_mview_ids() const { return mview_ids_; }
int set_mview_ids(const ObIArray<uint64_t> &mview_ids) { return mview_ids_.assign(mview_ids); }
public:
static const int64_t MAX_PRINTABLE_SIZE = 2 * 1024 * 1024;
private:
@ -692,7 +694,6 @@ public:
bool disable_auto_memory_mgr_;
private:
common::ObFixedArray<ObLocalSessionVar, common::ObIAllocator> all_local_session_vars_;
public:
bool udf_has_dml_stmt_;
private:

View File

@ -1257,5 +1257,16 @@ int ObPhysicalPlanCtx::init_param_store_after_deserialize()
return ret;
}
uint64_t ObPhysicalPlanCtx::get_last_refresh_scn(uint64_t mview_id) const
{
uint64_t last_refresh_scn = OB_INVALID_SCN_VAL;
for (int64_t i = 0; OB_INVALID_SCN_VAL == last_refresh_scn && i < mview_ids_.count(); ++i) {
if (mview_id == mview_ids_.at(i)) {
last_refresh_scn = last_refresh_scns_.at(i);
}
}
return last_refresh_scn;
}
} //sql
} //oceanbase

View File

@ -476,6 +476,9 @@ public:
ObIArray<ObArrayParamGroup> &get_array_param_groups() { return array_param_groups_; }
int set_all_local_session_vars(ObIArray<ObLocalSessionVar> &all_local_session_vars);
int get_local_session_vars(int64_t idx, const ObLocalSessionVar *&local_vars);
common::ObIArray<uint64_t> &get_mview_ids() { return mview_ids_; }
common::ObIArray<uint64_t> &get_last_refresh_scns() { return last_refresh_scns_; }
uint64_t get_last_refresh_scn(uint64_t mview_id) const;
void set_tx_id(int64_t tx_id) { tx_id_ = tx_id; }
int64_t get_tx_id() const { return tx_id_; }
void set_tm_sessid(int64_t tm_sessid) { tm_sessid_ = tm_sessid; }

View File

@ -30,6 +30,7 @@
#include "sql/ob_sql.h"
#include "share/scheduler/ob_tenant_dag_scheduler.h"
#include "storage/tx/ob_trans_service.h"
#include "sql/engine/expr/ob_expr_last_refresh_scn.h"
namespace oceanbase
{
@ -463,6 +464,14 @@ int ObRemoteBaseExecuteP<T>::execute_remote_plan(ObExecContext &exec_ctx,
LOG_WARN("created operator is NULL", K(ret));
} else if (OB_FAIL(plan_ctx->reserve_param_space(plan.get_param_count()))) {
LOG_WARN("reserve rescan param space failed", K(ret), K(plan.get_param_count()));
} else if (!plan.get_mview_ids().empty() && plan_ctx->get_mview_ids().empty()
&& OB_FAIL(ObExprLastRefreshScn::set_last_refresh_scns(plan.get_mview_ids(),
exec_ctx.get_sql_proxy(),
exec_ctx.get_my_session(),
exec_ctx.get_das_ctx().get_snapshot().core_.version_,
plan_ctx->get_mview_ids(),
plan_ctx->get_last_refresh_scns()))) {
LOG_WARN("fail to set last_refresh_scns", K(ret), K(plan.get_mview_ids()));
} else {
if (OB_FAIL(se_op->open())) {
LOG_WARN("fail open task", K(ret));

View File

@ -52,6 +52,7 @@
#include "storage/tx/ob_xa_ctx.h"
#include "sql/engine/dml/ob_link_op.h"
#include <cctype>
#include "sql/engine/expr/ob_expr_last_refresh_scn.h"
using namespace oceanbase::sql;
using namespace oceanbase::common;
@ -588,6 +589,14 @@ OB_INLINE int ObResultSet::do_open_plan(ObExecContext &ctx)
if (OB_FAIL(ret)) {
} else if (OB_FAIL(start_stmt())) {
LOG_WARN("fail start stmt", K(ret));
} else if (!physical_plan_->get_mview_ids().empty() && OB_PHY_PLAN_REMOTE != physical_plan_->get_plan_type()
&& OB_FAIL(ObExprLastRefreshScn::set_last_refresh_scns(physical_plan_->get_mview_ids(),
ctx.get_sql_proxy(),
ctx.get_my_session(),
ctx.get_das_ctx().get_snapshot().core_.version_,
ctx.get_physical_plan_ctx()->get_mview_ids(),
ctx.get_physical_plan_ctx()->get_last_refresh_scns()))) {
LOG_WARN("fail to set last_refresh_scns", K(ret), K(physical_plan_->get_mview_ids()));
} else {
/* 将exec_result_设置到executor的运行时环境中,用于返回数据 */
/* 执行plan,

View File

@ -23,6 +23,7 @@
#include "sql/rewrite/ob_transform_utils.h"
#include "sql/dblink/ob_dblink_utils.h"
#include "sql/engine/cmd/ob_table_direct_insert_service.h"
#include "sql/session/ob_sql_session_info.h"
using namespace oceanbase;
using namespace sql;
@ -69,7 +70,7 @@ int ObDelUpdLogPlan::compute_dml_parallel()
LOG_WARN("get unexpected parallel", K(ret), K(dml_parallel), K(opt_ctx.get_parallel_rule()));
} else {
max_dml_parallel_ = dml_parallel;
use_pdml_ = (opt_ctx.is_online_ddl() ||
use_pdml_ = (opt_ctx.is_online_ddl() || session_info->get_ddl_info().is_mview_complete_refresh() ||
(ObGlobalHint::DEFAULT_PARALLEL < dml_parallel &&
is_strict_mode(session_info->get_sql_mode())));
}

View File

@ -142,6 +142,7 @@ static const NonReservedKeyword Mysql_none_reserved_keywords[] =
{"completion", COMPLETION},
{"compressed", COMPRESSED},
{"compression", COMPRESSION},
{"computation", COMPUTATION},
{"compute", COMPUTE},
{"concurrent", CONCURRENT},
{"condensed", CONDENSED},
@ -413,6 +414,7 @@ static const NonReservedKeyword Mysql_none_reserved_keywords[] =
{"lag", LAG},
{"language", LANGUAGE},
{"last", LAST},
{"last_refresh_scn", LAST_REFRESH_SCN},
{"last_value", LAST_VALUE},
{"lateral", LATERAL},
{"lead", LEAD},
@ -721,6 +723,7 @@ static const NonReservedKeyword Mysql_none_reserved_keywords[] =
{"return", RETURN},
{"returns", RETURNS},
{"reverse", REVERSE},
{"rewrite", REWRITE},
{"revoke", REVOKE},
{"right", RIGHT},
{"rlike", REGEXP},

View File

@ -1020,6 +1020,8 @@ Timestamp{whitespace}?\"[^\"]*\" {
<hint>LEADING { return LEADING_HINT; }
<hint>ORDERED { return ORDERED; }
<hint>NO_REWRITE { return NO_REWRITE; }
<hint>MV_REWRITE { return MV_REWRITE; }
<hint>NO_MV_REWRITE { return NO_MV_REWRITE; }
<hint>FULL { return FULL_HINT; }
<hint>USE_MERGE { return USE_MERGE; }
<hint>NO_USE_MERGE { return NO_USE_MERGE; }

View File

@ -176,6 +176,7 @@ PROJECT_PRUNE NO_PROJECT_PRUNE SIMPLIFY_SET NO_SIMPLIFY_SET OUTER_TO_INNER NO_OU
COALESCE_SQ NO_COALESCE_SQ COUNT_TO_EXISTS NO_COUNT_TO_EXISTS LEFT_TO_ANTI NO_LEFT_TO_ANTI
ELIMINATE_JOIN NO_ELIMINATE_JOIN PUSH_LIMIT NO_PUSH_LIMIT PULLUP_EXPR NO_PULLUP_EXPR
WIN_MAGIC NO_WIN_MAGIC AGGR_FIRST_UNNEST NO_AGGR_FIRST_UNNEST JOIN_FIRST_UNNEST NO_JOIN_FIRST_UNNEST
MV_REWRITE NO_MV_REWRITE
DECORRELATE NO_DECORRELATE
// optimize hint
INDEX_HINT FULL_HINT NO_INDEX_HINT USE_DAS_HINT NO_USE_DAS_HINT
@ -272,7 +273,7 @@ END_P SET_VAR DELIMITER
CACHE CALIBRATION CALIBRATION_INFO CANCEL CASCADED CAST CATALOG_NAME CHAIN CHANGED CHARSET CHECKSUM CHECKPOINT CHUNK CIPHER
CLASS_ORIGIN CLEAN CLEAR CLIENT CLONE CLOG CLOSE CLUSTER CLUSTER_ID CLUSTER_NAME COALESCE COLUMN_STAT
CODE COLLATION COLUMN_FORMAT COLUMN_NAME COLUMNS COMMENT COMMIT COMMITTED COMPACT COMPLETION COMPLETE
COMPRESSED COMPRESSION COMPUTE CONCURRENT CONDENSED CONNECTION CONSISTENT CONSISTENT_MODE CONSTRAINT_CATALOG
COMPRESSED COMPRESSION COMPUTATION COMPUTE CONCURRENT CONDENSED CONNECTION CONSISTENT CONSISTENT_MODE CONSTRAINT_CATALOG
CONSTRAINT_NAME CONSTRAINT_SCHEMA CONTAINS CONTEXT CONTRIBUTORS COPY COUNT CPU CREATE_TIMESTAMP
CTXCAT CTX_ID CUBE CURDATE CURRENT STACKED CURTIME CURSOR_NAME CUME_DIST CYCLE CALC_PARTITION_ID CONNECT
@ -302,7 +303,8 @@ END_P SET_VAR DELIMITER
KEY_BLOCK_SIZE KEY_VERSION KVCACHE KV_ATTRIBUTES
LAG LANGUAGE LAST LAST_VALUE LATERAL LEAD LEADER LEAVES LESS LEAK LEAK_MOD LEAK_RATE LIB LINESTRING LIST_
LAG LANGUAGE LAST LAST_REFRESH_SCN LAST_VALUE LATERAL LEAD LEADER LEAVES LESS LEAK LEAK_MOD LEAK_RATE LIB LINESTRING LIST_
LISTAGG LOB_INROW_THRESHOLD LOCAL LOCALITY LOCATION LOCKED LOCKS LOGFILE LOGONLY_REPLICA_NUM LOGS LOCK_ LOGICAL_READS
LEVEL LN LOG LS LINK LOG_RESTORE_SOURCE LINE_DELIMITER
@ -336,7 +338,7 @@ END_P SET_VAR DELIMITER
REBUILD RECOVER RECOVERY_WINDOW RECYCLE REDO_BUFFER_SIZE REDOFILE REDUNDANCY REDUNDANT REFRESH REGION RELAY RELAYLOG
RELAY_LOG_FILE RELAY_LOG_POS RELAY_THREAD RELOAD REMAP REMOVE REORGANIZE REPAIR REPEATABLE REPLICA
REPLICA_NUM REPLICA_TYPE REPLICATION REPORT RESET RESOURCE RESOURCE_POOL RESOURCE_POOL_LIST RESPECT RESTART
RESTORE RESUME RETURNED_SQLSTATE RETURNS RETURNING REVERSE ROLLBACK ROLLUP ROOT
RESTORE RESUME RETURNED_SQLSTATE RETURNS RETURNING REVERSE REWRITE ROLLBACK ROLLUP ROOT
ROOTTABLE ROOTSERVICE ROOTSERVICE_LIST ROUTINE ROW ROLLING ROWID ROW_COUNT ROW_FORMAT ROWS RTREE RUN
RECYCLEBIN ROTATE ROW_NUMBER RUDUNDANT RECURSIVE RANDOM REDO_TRANSPORT_OPTIONS REMOTE_OSS RT
RANK READ_ONLY RECOVERY REJECT ROLE
@ -418,7 +420,7 @@ END_P SET_VAR DELIMITER
%type <node> sort_list sort_key opt_asc_desc sort_list_for_group_by sort_key_for_group_by opt_asc_desc_for_group_by opt_column_id
%type <node> opt_query_expression_option_list query_expression_option_list query_expression_option opt_distinct opt_distinct_or_all opt_separator projection
%type <node> from_list table_references table_reference table_factor normal_relation_factor dot_relation_factor relation_factor
%type <node> relation_factor_in_hint relation_factor_in_hint_list relation_factor_in_pq_hint opt_relation_factor_in_hint_list relation_factor_in_use_join_hint_list
%type <node> relation_factor_in_hint relation_factor_in_hint_list relation_factor_in_pq_hint opt_relation_factor_in_hint_list relation_factor_in_use_join_hint_list relation_factor_in_mv_hint_list opt_relation_factor_in_mv_hint_list
%type <node> relation_factor_in_leading_hint_list joined_table tbl_name table_subquery table_subquery_alias
%type <node> relation_factor_with_star relation_with_star_list opt_with_star
%type <node> index_hint_type key_or_index index_hint_scope index_element index_list opt_index_list
@ -474,9 +476,9 @@ END_P SET_VAR DELIMITER
%type <node> drop_index_stmt hint_options opt_expr_as_list expr_as_list expr_with_opt_alias substr_params opt_comma substr_or_substring
%type <node> /*frozen_type*/ opt_binary
%type <node> ip_port
%type <node> create_view_stmt view_name opt_column_list opt_table_id opt_tablet_id view_select_stmt opt_check_option opt_tablet_id_no_empty
%type <node> create_mview_stmt create_mview_refresh mv_refresh_on_clause mv_refresh_mode mv_refresh_interval mv_start_clause mv_next_clause
%type <ival> mv_refresh_method
%type <node> create_view_stmt view_name opt_column_list opt_mv_column_list mv_column_list opt_table_id opt_tablet_id view_select_stmt opt_check_option opt_tablet_id_no_empty
%type <node> create_mview_stmt create_mview_opts mview_refresh_opt mv_refresh_on_clause mv_refresh_mode mv_refresh_interval mv_start_clause mv_next_clause
%type <ival> mv_refresh_method mview_enable_disable
%type <node> name_list
%type <node> partition_role ls_role zone_desc opt_zone_desc server_or_zone opt_server_or_zone opt_partitions opt_subpartitions add_or_alter_zone_options alter_or_change_or_modify
%type <node> ls opt_tenant_list_or_ls_or_tablet_id ls_server_or_server_or_zone_or_tenant add_or_alter_zone_option
@ -3075,6 +3077,10 @@ MOD '(' expr ',' expr ')'
malloc_non_terminal_node($$, result->malloc_pool_, T_FUN_SYS_ST_ASMVT, 5, $3, $5, $7, $9, $11);
$$->reserved_ = 0;
}
| LAST_REFRESH_SCN '(' INTNUM ')'
{
malloc_non_terminal_node($$, result->malloc_pool_, T_FUN_SYS_LAST_REFRESH_SCN, 1, $3);
}
| SUM_OPNSIZE '(' expr ')'
{
malloc_non_terminal_node($$, result->malloc_pool_, T_FUN_SUM_OPNSIZE, 2, NULL, $3);
@ -8100,7 +8106,8 @@ create_with_opt_hint opt_replace opt_algorithm opt_definer opt_sql_security VIEW
*
*****************************************************************************/
create_mview_stmt:
create_with_opt_hint MATERIALIZED VIEW view_name opt_column_list opt_table_option_list opt_partition_option create_mview_refresh AS view_select_stmt opt_check_option
create_with_opt_hint MATERIALIZED VIEW view_name opt_mv_column_list opt_table_option_list opt_partition_option create_mview_opts
AS view_select_stmt opt_check_option
{
ParseNode *table_options = NULL;
merge_nodes(table_options, result, T_TABLE_OPTION_LIST, $6);
@ -8114,7 +8121,7 @@ create_with_opt_hint MATERIALIZED VIEW view_name opt_column_list opt_table_optio
NULL,
$11, /* with option */
NULL, /* force view opt */
$8,
$8, /* mview options */
$7, /* partition option */
table_options, /* table options */
$1 /* hint */
@ -8124,7 +8131,46 @@ create_with_opt_hint MATERIALIZED VIEW view_name opt_column_list opt_table_optio
}
;
create_mview_refresh:
create_mview_opts:
mview_refresh_opt
{
malloc_non_terminal_node($$, result->malloc_pool_, T_MV_OPTIONS, 1, $1);
$$->value_ = 0;
}
| mview_refresh_opt mview_enable_disable ON QUERY COMPUTATION
{
malloc_non_terminal_node($$, result->malloc_pool_, T_MV_OPTIONS, 1, $1);
$$->value_ = $2[0];
}
| mview_refresh_opt mview_enable_disable QUERY REWRITE
{
malloc_non_terminal_node($$, result->malloc_pool_, T_MV_OPTIONS, 1, $1);
$$->value_ = $2[0] << 1;
}
| mview_refresh_opt mview_enable_disable ON QUERY COMPUTATION mview_enable_disable QUERY REWRITE
{
malloc_non_terminal_node($$, result->malloc_pool_, T_MV_OPTIONS, 1, $1);
$$->value_ = $2[0] | ($6[0] << 1);
}
| mview_refresh_opt mview_enable_disable QUERY REWRITE mview_enable_disable ON QUERY COMPUTATION
{
malloc_non_terminal_node($$, result->malloc_pool_, T_MV_OPTIONS, 1, $1);
$$->value_ = $5[0] | ($2[0] << 1);
}
;
mview_enable_disable:
DISABLE
{
$$[0] = 0;
}
| ENABLE
{
$$[0] = 1;
}
;
mview_refresh_opt:
REFRESH mv_refresh_method mv_refresh_on_clause mv_refresh_interval
{
malloc_non_terminal_node($$, result->malloc_pool_, T_MV_REFRESH_INFO, 2,
@ -8295,6 +8341,35 @@ relation_factor
{ $$ = $1; }
;
opt_mv_column_list:
'(' mv_column_list ')'
{
merge_nodes($$, result, T_COLUMN_LIST, $2);
}
| /*EMPTY*/ { $$ = NULL; }
;
mv_column_list:
column_name_list
{
$$ = $1;
}
| column_name_list ',' PRIMARY KEY opt_index_using_algorithm '(' column_name_list ')' opt_index_using_algorithm opt_comment
{
ParseNode *col_list= NULL;
ParseNode *pk_node = NULL;
merge_nodes(col_list, result, T_COLUMN_LIST, $7);
malloc_non_terminal_node(pk_node, result->malloc_pool_, T_PRIMARY_KEY, 3, col_list, NULL != $9 ? $9 : $5, $10);
malloc_non_terminal_node($$, result->malloc_pool_, T_LINK_NODE, 2, $1, pk_node);
}
| PRIMARY KEY opt_index_using_algorithm '(' column_name_list ')' opt_index_using_algorithm opt_comment
{
ParseNode *col_list= NULL;
merge_nodes(col_list, result, T_COLUMN_LIST, $5);
malloc_non_terminal_node($$, result->malloc_pool_, T_PRIMARY_KEY, 3, col_list, NULL != $7 ? $7 : $3, $8);
}
;
opt_column_list:
'(' column_name_list ')'
{
@ -10215,6 +10290,18 @@ NO_REWRITE opt_qb_name
{
malloc_non_terminal_node($$, result->malloc_pool_, T_NO_REWRITE, 1, $2);
}
| MV_REWRITE
{
malloc_non_terminal_node($$, result->malloc_pool_, T_MV_REWRITE, 2, NULL, NULL);
}
| MV_REWRITE '(' qb_name_option opt_relation_factor_in_mv_hint_list ')'
{
malloc_non_terminal_node($$, result->malloc_pool_, T_MV_REWRITE, 2, $3, $4);
}
| NO_MV_REWRITE opt_qb_name
{
malloc_non_terminal_node($$, result->malloc_pool_, T_MV_NO_REWRITE, 1, $2);
}
| MERGE_HINT opt_qb_name
{
malloc_non_terminal_node($$, result->malloc_pool_, T_MERGE_HINT, 2, $2, NULL);
@ -12355,6 +12442,30 @@ relation_sep_option:
{}
;
relation_factor_in_mv_hint_list:
normal_relation_factor
{
malloc_non_terminal_node($$, result->malloc_pool_, T_RELATION_FACTOR_IN_HINT, 2, $1, NULL);
}
| relation_factor_in_mv_hint_list relation_sep_option normal_relation_factor
{
ParseNode *mock_rel_in_hint_node = NULL;
malloc_non_terminal_node(mock_rel_in_hint_node, result->malloc_pool_, T_RELATION_FACTOR_IN_HINT, 2, $3, NULL);
malloc_non_terminal_node($$, result->malloc_pool_, T_LINK_NODE, 2, $1, mock_rel_in_hint_node);
}
;
opt_relation_factor_in_mv_hint_list:
/* EMPTY */
{
$$ = NULL;
}
| relation_factor_in_mv_hint_list
{
merge_nodes($$, result, T_RELATION_FACTOR_IN_HINT_LIST, $1);
}
;
opt_relation_factor_in_hint_list:
/* EMPTY */
{
@ -20520,6 +20631,7 @@ ACCOUNT
| COMPLETION
| COMPRESSED
| COMPRESSION
| COMPUTATION
| COMPUTE
| CONCURRENT
| CONDENSED
@ -20701,6 +20813,7 @@ ACCOUNT
| LATERAL %prec LOWER_PARENS
| LANGUAGE
| LAST
| LAST_REFRESH_SCN
| LAST_VALUE
| LEAD
| LEADER
@ -20935,6 +21048,7 @@ ACCOUNT
| RETURNING
| RETURNS
| REVERSE
| REWRITE
| ROLE
| ROLLBACK
| ROLLING

View File

@ -3304,6 +3304,10 @@ int ObRawExprPrinter::print(ObSysFunRawExpr *expr)
PRINT_EXPR(expr->get_param_expr(2));
break;
}
case T_FUN_SYS_LAST_REFRESH_SCN: {
DATA_PRINTF("%.*s(%ld)", LEN_AND_PTR(func_name), expr->get_mview_id());
break;
}
// for bugfix: 52438113/52226266
case T_FUN_SYS_PRIV_SQL_UDT_CONSTRUCT: {
OZ(print_sql_udt_construct(expr));

View File

@ -258,6 +258,14 @@ int ObCreateIndexResolver::resolve_index_column_node(
}
}
if (OB_SUCC(ret) && cnt_func_index) {
if (OB_UNLIKELY(tbl_schema->mv_container_table())) {
ret = OB_NOT_SUPPORTED;
LOG_WARN("use functional index on materialized view not supported", K(ret), KPC(tbl_schema));
LOG_USER_ERROR(OB_NOT_SUPPORTED, "use functional index on materialized view");
}
}
// In oracle mode, we need to check if the new index is on the same cols with old indexes.
CHECK_COMPATIBILITY_MODE(session_info_);
if (OB_SUCC(ret) && lib::is_oracle_mode()) {

View File

@ -90,76 +90,33 @@ int ObCreateTableResolver::add_primary_key_part(const ObString &column_name,
{
int ret = OB_SUCCESS;
ObCreateTableStmt *create_table_stmt = static_cast<ObCreateTableStmt*>(stmt_);
bool is_oracle_mode = lib::is_oracle_mode();
if (OB_ISNULL(session_info_) || OB_ISNULL(create_table_stmt)) {
ObColumnSchemaV2 *col = NULL;
if (OB_ISNULL(create_table_stmt)) {
ret = OB_NOT_INIT;
SQL_RESV_LOG(WARN, "session or stmt is null", KP(session_info_), KP(create_table_stmt), K(ret));
} else if (static_cast<int64_t>(table_id_) > 0
&& OB_FAIL(ObCompatModeGetter::check_is_oracle_mode_with_table_id(
session_info_->get_effective_tenant_id(), table_id_, is_oracle_mode))) {
LOG_WARN("fail to check oracle mode", KR(ret), K_(table_id));
} else {
ObColumnSchemaV2 *col = NULL;
ObTableSchema &table_schema = create_table_stmt->get_create_table_arg().schema_;
col = table_schema.get_column_schema(column_name);
if (OB_ISNULL(col)) {
ret = OB_ERR_KEY_COLUMN_DOES_NOT_EXITS;
LOG_USER_ERROR(OB_ERR_KEY_COLUMN_DOES_NOT_EXITS, column_name.length(), column_name.ptr());
SQL_RESV_LOG(WARN, "column '%s' does not exists", K(ret), K(to_cstring(column_name)));
} else if (OB_FAIL(check_add_column_as_pk_allowed(*col))) {
LOG_WARN("the column can not be primary key", K(ret));
} else {
int64_t index = -1;
bool is_found = false;
for (int64_t i = 0; OB_SUCC(ret) && !is_found && i < stats.count(); ++i) {
if (stats.at(i).column_id_ == col->get_column_id()) {
index = i;
is_found = true;
}
}
if (-1 == index) {
ret = OB_ERR_UNEXPECTED;
SQL_RESV_LOG(WARN, "fail to find column stat", K(ret), K(column_name));
} else if (!is_oracle_mode) {
// mysql 模式下,建表时主键列被 set null 或被 set default value = null,都要报错
// oracle 模式下,建表时主键列被 set null 或被 set default value = null,都不会报错,所以跳过下面这个检查
if (stats.at(index).is_set_null_
|| (stats.at(index).is_set_default_value_ && col->get_cur_default_value().is_null())) {
ret = OB_ERR_PRIMARY_CANT_HAVE_NULL;
}
} else { /*do nothing*/ }
}
if (OB_SUCC(ret)) {
if (col->get_rowkey_position() > 0) {
ret = OB_ERR_COLUMN_DUPLICATE;
LOG_USER_ERROR(OB_ERR_COLUMN_DUPLICATE, column_name.length(), column_name.ptr());
} else if (OB_USER_MAX_ROWKEY_COLUMN_NUMBER == primary_keys_.count()) {
ret = OB_ERR_TOO_MANY_ROWKEY_COLUMNS;
LOG_USER_ERROR(OB_ERR_TOO_MANY_ROWKEY_COLUMNS, OB_USER_MAX_ROWKEY_COLUMN_NUMBER);
} else if (col->is_string_type()) {
int64_t length = 0;
if (OB_FAIL(col->get_byte_length(length, is_oracle_mode, false))) {
SQL_RESV_LOG(WARN, "fail to get byte length of column", KR(ret), K(is_oracle_mode));
} else if ((pk_data_length += length) > OB_MAX_USER_ROW_KEY_LENGTH) {
ret = OB_ERR_TOO_LONG_KEY_LENGTH;
LOG_USER_ERROR(OB_ERR_TOO_LONG_KEY_LENGTH, OB_MAX_USER_ROW_KEY_LENGTH);
} else if (length <= 0) {
ret = OB_ERR_WRONG_KEY_COLUMN;
LOG_USER_ERROR(OB_ERR_WRONG_KEY_COLUMN, column_name.length(), column_name.ptr());
} else {
// do nothing
}
SQL_RESV_LOG(WARN, "stmt is null", KP(create_table_stmt), K(ret));
} else if (OB_FAIL(ObCreateTableResolverBase::add_primary_key_part(column_name,
create_table_stmt->get_create_table_arg().schema_,
primary_keys_.count(),
pk_data_length,
col))) {
LOG_WARN("failed to add primary key part", KR(ret), K(column_name));
} else if (OB_FAIL(primary_keys_.push_back(col->get_column_id()))) {
SQL_RESV_LOG(WARN, "push primary key to array failed", K(ret));
} else if (!lib::is_oracle_mode()) {
// mysql 模式下,建表时主键列被 set null 或被 set default value = null,都要报错
// oracle 模式下,建表时主键列被 set null 或被 set default value = null,都不会报错,所以跳过下面这个检查
ObColumnResolveStat *stat = NULL;
for (int64_t i = 0; NULL == stat && OB_SUCC(ret) && i < stats.count(); ++i) {
if (stats.at(i).column_id_ == col->get_column_id()) {
stat = &stats.at(i);
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(primary_keys_.push_back(col->get_column_id()))) {
SQL_RESV_LOG(WARN, "push primary key to array failed", K(ret));
} else {
col->set_rowkey_position(primary_keys_.count());
col->set_nullable(false);
ret = table_schema.set_rowkey_info(*col);
}
if (OB_FAIL(ret)) {
} else if (OB_ISNULL(stat)) {
ret = OB_ERR_UNEXPECTED;
SQL_RESV_LOG(WARN, "fail to find column stat", K(ret), K(column_name));
} else if (stat->is_set_null_ || (stat->is_set_default_value_ && col->get_cur_default_value().is_null())) {
ret = OB_ERR_PRIMARY_CANT_HAVE_NULL;
}
}
return ret;

View File

@ -400,5 +400,52 @@ int ObCreateTableResolverBase::set_table_option_to_schema(ObTableSchema &table_s
return ret;
}
int ObCreateTableResolverBase::add_primary_key_part(const ObString &column_name,
ObTableSchema &table_schema,
const int64_t cur_rowkey_size,
int64_t &pk_data_length,
ObColumnSchemaV2 *&col)
{
int ret = OB_SUCCESS;
col = NULL;
bool is_oracle_mode = lib::is_oracle_mode();
int64_t length = 0;
if (OB_ISNULL(session_info_)) {
ret = OB_NOT_INIT;
SQL_RESV_LOG(WARN, "session is null", KP(session_info_), K(ret));
} else if (static_cast<int64_t>(table_id_) > 0
&& OB_FAIL(ObCompatModeGetter::check_is_oracle_mode_with_table_id(
session_info_->get_effective_tenant_id(), table_id_, is_oracle_mode))) {
LOG_WARN("fail to check oracle mode", KR(ret), K_(table_id));
} else if (OB_ISNULL(col = table_schema.get_column_schema(column_name))) {
ret = OB_ERR_KEY_COLUMN_DOES_NOT_EXITS;
LOG_USER_ERROR(OB_ERR_KEY_COLUMN_DOES_NOT_EXITS, column_name.length(), column_name.ptr());
SQL_RESV_LOG(WARN, "column '%s' does not exists", K(ret), K(to_cstring(column_name)));
} else if (OB_FAIL(check_add_column_as_pk_allowed(*col))) {
LOG_WARN("the column can not be primary key", K(ret));
} else if (col->get_rowkey_position() > 0) {
ret = OB_ERR_COLUMN_DUPLICATE;
LOG_USER_ERROR(OB_ERR_COLUMN_DUPLICATE, column_name.length(), column_name.ptr());
} else if (OB_USER_MAX_ROWKEY_COLUMN_NUMBER == cur_rowkey_size) {
ret = OB_ERR_TOO_MANY_ROWKEY_COLUMNS;
LOG_USER_ERROR(OB_ERR_TOO_MANY_ROWKEY_COLUMNS, OB_USER_MAX_ROWKEY_COLUMN_NUMBER);
} else if (OB_FALSE_IT(col->set_nullable(false))
|| OB_FALSE_IT(col->set_rowkey_position(cur_rowkey_size + 1))) {
} else if (OB_FAIL(table_schema.set_rowkey_info(*col))) {
LOG_WARN("failed to set rowkey info", K(ret));
} else if (!col->is_string_type()) {
/* do nothing */
} else if (OB_FAIL(col->get_byte_length(length, is_oracle_mode, false))) {
SQL_RESV_LOG(WARN, "fail to get byte length of column", KR(ret), K(is_oracle_mode));
} else if ((pk_data_length += length) > OB_MAX_USER_ROW_KEY_LENGTH) {
ret = OB_ERR_TOO_LONG_KEY_LENGTH;
LOG_USER_ERROR(OB_ERR_TOO_LONG_KEY_LENGTH, OB_MAX_USER_ROW_KEY_LENGTH);
} else if (length <= 0) {
ret = OB_ERR_WRONG_KEY_COLUMN;
LOG_USER_ERROR(OB_ERR_WRONG_KEY_COLUMN, column_name.length(), column_name.ptr());
}
return ret;
}
}//end namespace sql
}//end namespace oceanbase

View File

@ -38,6 +38,11 @@ protected:
share::schema::ObTableSchema &table_schema,
const bool is_partition_option_node_with_opt);
int set_table_option_to_schema(share::schema::ObTableSchema &table_schema);
int add_primary_key_part(const ObString &column_name,
ObTableSchema &table_schema,
const int64_t cur_rowkey_size,
int64_t &pk_data_length,
ObColumnSchemaV2 *&col);
};

View File

@ -26,6 +26,7 @@
#include "storage/mview/ob_mview_sched_job_utils.h"
#include "sql/resolver/mv/ob_mv_checker.h"
#include "observer/virtual_table/ob_table_columns.h"
#include "sql/rewrite/ob_transformer_impl.h"
namespace oceanbase
{
@ -130,6 +131,7 @@ int ObCreateViewResolver::resolve(const ParseNode &parse_tree)
ObArray<ObString> column_list;
ObArray<ObString> comment_list;
bool has_dblink_node = false;
ParseNode *mv_primary_key_node = NULL;
share::schema::ObSchemaGetterGuard *schema_guard = NULL;
uint64_t database_id = OB_INVALID_ID;
ObString old_database_name;
@ -279,8 +281,12 @@ int ObCreateViewResolver::resolve(const ParseNode &parse_tree)
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(resolve_column_list(view_columns_node,
column_list))) {
column_list,
mv_primary_key_node))) {
LOG_WARN("fail to resolve view columns", K(ret));
} else if (OB_UNLIKELY(!is_materialized_view && NULL != mv_primary_key_node)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected primary key node for non materialized view", K(ret));
} else if (OB_ISNULL(select_stmt = view_table_resolver.get_select_stmt())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret), K(view_table_resolver.get_select_stmt()));
@ -372,69 +378,33 @@ int ObCreateViewResolver::resolve(const ParseNode &parse_tree)
}
}
if (is_materialized_view) { //container table is only for mv
if (OB_SUCC(ret)) {
if (OB_FAIL(ObResolverUtils::check_schema_valid_for_mview(table_schema))) {
LOG_WARN("failed to check schema valid for mview", KR(ret), K(table_schema));
} else if (OB_FAIL(resolve_table_options(parse_tree.children_[TABLE_OPTION_NODE], false))) {
LOG_WARN("fail to resolve table options", KR(ret));
}
}
SMART_VAR(ObMVAdditionalInfo, mv_ainfo) {
ObTableSchema &container_table_schema = mv_ainfo.container_table_schema_;
if (OB_SUCC(ret)) {
if (OB_FAIL(container_table_schema.assign(table_schema))) {
LOG_WARN("fail to assign table schema", KR(ret));
} else {
container_table_schema.set_table_type(ObTableType::USER_TABLE);
container_table_schema.get_view_schema().reset();
container_table_schema.set_max_dependency_version(OB_INVALID_VERSION);
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(add_hidden_tablet_seq_col(container_table_schema))) {
LOG_WARN("fail to add hidden pk", KR(ret));
}
}
if (OB_SUCC(ret)) {
pctfree_ = 0; // set default pctfree value for non-sys table
if (OB_FAIL(resolve_partition_option(parse_tree.children_[PARTITION_NODE], container_table_schema, true))) {
LOG_WARN("fail to resolve_partition_option", KR(ret));
} else if (OB_FAIL(set_table_option_to_schema(container_table_schema))) {
SQL_RESV_LOG(WARN, "set table option to schema failed", KR(ret));
} else {
container_table_schema.set_collation_type(collation_type_);
container_table_schema.set_charset_type(charset_type_);
container_table_schema.set_table_pk_mode(TPKM_TABLET_SEQ_PK); //非主键表需要设置这个
container_table_schema.set_table_organization_mode(TOM_HEAP_ORGANIZED);
container_table_schema.set_mv_container_table(IS_MV_CONTAINER_TABLE);
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(resolve_hints(parse_tree.children_[HINT_NODE], *stmt, container_table_schema))) {
LOG_WARN("resolve hints failed", K(ret));
} else {
mv_ainfo.mv_refresh_info_.parallel_ = stmt->get_parallelism();
}
}
if (OB_SUCC(ret)) {
ObViewSchema &view_schema = table_schema.get_view_schema();
if (OB_FAIL(resolve_mv_refresh_info(parse_tree.children_[MVIEW_NODE], mv_ainfo.mv_refresh_info_))) {
LOG_WARN("fail to resolve mv refresh info", KR(ret));
} else if (ObMVRefreshMethod::FAST == mv_ainfo.mv_refresh_info_.refresh_method_
&& OB_FAIL(ObMVChecker::check_mv_fast_refresh_valid(select_stmt,
params_.expr_factory_,
params_.session_info_))) {
LOG_WARN("fail to check fast refresh valid", K(ret));
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(create_arg.mv_ainfo_.push_back(mv_ainfo))) {
LOG_WARN("fail to push back container table schema", KR(ret));
}
}
if (OB_SUCC(ret) && is_materialized_view) {
ObMVAdditionalInfo *mv_ainfo = NULL;
ObCreateTableStmt *create_table_stmt = static_cast<ObCreateTableStmt*>(stmt_);
ObSEArray<ObConstraint,4> &csts = create_table_stmt->get_create_table_arg().constraint_list_;
if (OB_FAIL(ObResolverUtils::check_schema_valid_for_mview(table_schema))) {
LOG_WARN("failed to check schema valid for mview", KR(ret), K(table_schema));
} else if (OB_FAIL(resolve_table_options(parse_tree.children_[TABLE_OPTION_NODE], false))) {
LOG_WARN("fail to resolve table options", KR(ret));
} else if (OB_ISNULL(mv_ainfo = create_arg.mv_ainfo_.alloc_place_holder())) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("Allocate ObMVAdditionalInfo from array error", K(ret));
} else if (OB_FAIL(mv_ainfo->container_table_schema_.assign(table_schema))) {
LOG_WARN("fail to assign table schema", KR(ret));
} else if (OB_FAIL(resolve_materialized_view_container_table(parse_tree.children_[PARTITION_NODE],
mv_primary_key_node,
mv_ainfo->container_table_schema_,
csts))) {
LOG_WARN("fail do resolve for materialized view", K(ret));
} else if (OB_FAIL(resolve_mv_options(select_stmt,
parse_tree.children_[MVIEW_NODE],
mv_ainfo->mv_refresh_info_,
table_schema))) {
LOG_WARN("fail to resolve mv options", K(ret));
} else if (OB_FAIL(resolve_hints(parse_tree.children_[HINT_NODE], *stmt, mv_ainfo->container_table_schema_))) {
LOG_WARN("resolve hints failed", K(ret));
} else {
mv_ainfo->mv_refresh_info_.parallel_ = stmt->get_parallelism();
}
}
@ -502,6 +472,91 @@ int ObCreateViewResolver::try_add_error_info(const uint64_t error_number,
return ret;
}
int ObCreateViewResolver::resolve_materialized_view_container_table(ParseNode *partition_node,
ParseNode *mv_primary_key_node,
ObTableSchema &container_table_schema,
ObSEArray<ObConstraint,4>& csts)
{
int ret = OB_SUCCESS;
container_table_schema.set_table_type(ObTableType::USER_TABLE);
container_table_schema.get_view_schema().reset();
container_table_schema.set_max_dependency_version(OB_INVALID_VERSION);
pctfree_ = 0; // set default pctfree value for non-sys table
if (OB_FAIL(resolve_partition_option(partition_node, container_table_schema, true))) {
LOG_WARN("fail to resolve_partition_option", KR(ret));
} else if (OB_FAIL(set_table_option_to_schema(container_table_schema))) {
SQL_RESV_LOG(WARN, "set table option to schema failed", KR(ret));
} else if (NULL != mv_primary_key_node
&& OB_FAIL(resolve_primary_key_node(*mv_primary_key_node, container_table_schema))) {
LOG_WARN("failed to resolve primary key node", K(ret));
} else if (0 < container_table_schema.get_rowkey_column_num()) { // create mv with primary key
container_table_schema.set_table_pk_mode(ObTablePKMode::TPKM_OLD_NO_PK);
container_table_schema.set_table_organization_mode(ObTableOrganizationMode::TOM_INDEX_ORGANIZED);
if (is_oracle_mode() && OB_FAIL(resolve_pk_constraint_node(*mv_primary_key_node, ObString::make_empty_string(), csts))) {
LOG_WARN("failed to add pk constraint for oracle mode", KR(ret));
}
} else if (OB_FAIL(add_hidden_tablet_seq_col(container_table_schema))) {
LOG_WARN("fail to add hidden pk", KR(ret));
} else { // create mv without primary key
container_table_schema.set_table_pk_mode(TPKM_TABLET_SEQ_PK);
container_table_schema.set_table_organization_mode(TOM_HEAP_ORGANIZED);
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(container_table_schema.check_primary_key_cover_partition_column())) {
SQL_RESV_LOG(WARN, "fail to check primary key cover partition column", KR(ret));
} else {
container_table_schema.set_collation_type(collation_type_);
container_table_schema.set_charset_type(charset_type_);
container_table_schema.set_mv_container_table(IS_MV_CONTAINER_TABLE);
}
return ret;
}
int ObCreateViewResolver::resolve_primary_key_node(ParseNode &pk_node,
ObTableSchema &table_schema)
{
int ret = OB_SUCCESS;
ParseNode *cur_node = NULL;
if (OB_UNLIKELY(2 > pk_node.num_child_) || OB_ISNULL(cur_node = pk_node.children_[0])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected params", K(ret), K(pk_node.num_child_), K(cur_node));
} else if (OB_UNLIKELY(T_COLUMN_LIST != cur_node->type_ || cur_node->num_child_ <= 0)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected node", K(ret), K(get_type_name(cur_node->type_)), K(cur_node->num_child_));
} else {
ParseNode *key_node = NULL;
int64_t pk_data_length = 0;
ObColumnSchemaV2 *col = NULL;
for (int32_t i = 0; OB_SUCC(ret) && i < cur_node->num_child_; ++i) {
if (OB_ISNULL(key_node = cur_node->children_[i])) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret), K(i));
} else if (OB_FAIL(ObCreateTableResolverBase::add_primary_key_part(ObString(key_node->str_len_, key_node->str_value_),
table_schema, i,
pk_data_length, col))) {
LOG_WARN("failed to add primary key part", K(ret), K(i));
}
}
if (OB_FAIL(ret) || is_oracle_mode()) {
} else if (OB_UNLIKELY(3 != pk_node.num_child_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected params", K(ret), K(pk_node.num_child_));
} else {
if (NULL != (cur_node = pk_node.children_[1])) {
table_schema.set_index_using_type(T_USING_HASH == cur_node->type_ ? share::schema::USING_HASH
: share::schema::USING_BTREE);
}
if (NULL != (cur_node = pk_node.children_[2])) {
if (OB_FAIL(table_schema.set_pk_comment(ObString(cur_node->str_len_, cur_node->str_value_)))) {
LOG_WARN("fail to set primary key comment", K(ret), K(ObString(cur_node->str_len_, cur_node->str_value_)));
}
}
}
}
return ret;
}
int ObCreateViewResolver::check_view_columns(ObSelectStmt &select_stmt,
ParseNode *view_columns_node,
share::schema::ObErrorInfo &error_info,
@ -519,39 +574,46 @@ int ObCreateViewResolver::check_view_columns(ObSelectStmt &select_stmt,
ObString dup_col_name;
hash::ObHashSet<ObString> view_col_names;
int64_t select_item_size = select_stmt.get_select_item_size();
if (NULL != view_columns_node && view_columns_node->num_child_ > 0) {
ObCollationType cs_type = CS_TYPE_INVALID;
if (OB_UNLIKELY(!is_force_view && select_item_size != view_columns_node->num_child_)) {
ret = OB_ERR_VIEW_WRONG_LIST;
LOG_WARN("view columns is not equal with select columns", K(select_item_size),
K(view_columns_node->num_child_));
} else if (OB_FAIL(session_info_->get_collation_connection(cs_type))) {
LOG_WARN("fail to get collation_connection", K(ret));
} else if (OB_FAIL(view_col_names.create(view_columns_node->num_child_))) {
LOG_WARN("failed to init hashset", K(ret), K(select_stmt.get_select_items().count()));
} else if (is_force_view && select_item_size != view_columns_node->num_child_) {
if (OB_FAIL(try_add_error_info(OB_ERR_VIEW_WRONG_LIST, error_info))) {
LOG_WARN("failed to add error info to for force view", K(ret));
} else {
can_expand_star = false;
add_undefined_columns = true;
LOG_TRACE("force view columns is not equal with select columns", K(select_item_size),
K(view_columns_node->num_child_));
}
bool has_view_columns_node = false;
ObCollationType cs_type = CS_TYPE_INVALID;
if ((!is_force_view || select_item_size > 0)
&& OB_FAIL(view_col_names.create(select_item_size))) {
LOG_WARN("failed to init hashset", K(ret), K(select_item_size));
} else if (NULL == view_columns_node || view_columns_node->num_child_ <= 0) {
/* do nothing */
} else if (is_force_view && select_item_size != view_columns_node->num_child_) {
has_view_columns_node = true;
if (OB_FAIL(try_add_error_info(OB_ERR_VIEW_WRONG_LIST, error_info))) {
LOG_WARN("failed to add error info to for force view", K(ret));
} else {
can_expand_star = false;
add_undefined_columns = true;
LOG_TRACE("force view columns is not equal with select columns", K(select_item_size),
K(view_columns_node->num_child_));
}
} else if (OB_FAIL(session_info_->get_collation_connection(cs_type))) {
LOG_WARN("fail to get collation_connection", K(ret));
} else {
ParseNode *child_node = NULL;
int64_t col_cnt_from_node = 0;
for (int64_t i = 0; OB_SUCC(ret) && !is_col_dup && i < view_columns_node->num_child_; i++) {
if (OB_ISNULL(view_columns_node->children_[i])) {
if (OB_ISNULL(child_node = view_columns_node->children_[i])) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid null children", K(ret), K(view_columns_node->children_[i]));
} else if (FALSE_IT(dup_col_name = ObString::make_string(view_columns_node->children_[i]->str_value_))) {
LOG_WARN("invalid null children", K(ret), K(i), K(child_node));
} else if (T_PRIMARY_KEY == child_node->type_) {
/* do nothing */
} else if (FALSE_IT(dup_col_name = ObString::make_string(child_node->str_value_))) {
} else if (OB_FAIL(ObCharset::tolower(cs_type, dup_col_name, dup_col_name, *allocator_))) {
LOG_WARN("fail to lower string", K(ret));
} else if (OB_HASH_EXIST == (ret = view_col_names.set_refactored(dup_col_name, 0))) {
++col_cnt_from_node;
is_col_dup = true;
ret = OB_SUCCESS;
} else if (OB_FAIL(ret)) {
LOG_WARN("failed to set hashset", K(ret));
} else { /* do nothing */ }
} else {
++col_cnt_from_node;
}
}
if (OB_SUCC(ret) && lib::is_oracle_mode() && can_expand_star && select_item_size > 0) {
hash::ObHashSet<ObString> select_item_names;
@ -570,6 +632,17 @@ int ObCreateViewResolver::check_view_columns(ObSelectStmt &select_stmt,
}
}
}
if (OB_FAIL(ret) || 0 == col_cnt_from_node) {
} else if (OB_UNLIKELY(select_item_size != col_cnt_from_node)) {
ret = OB_ERR_VIEW_WRONG_LIST;
LOG_WARN("view columns is not equal with select columns", K(select_item_size),
K(col_cnt_from_node), K(view_columns_node->num_child_));
} else {
has_view_columns_node = true;
}
}
if (OB_FAIL(ret) || has_view_columns_node) {
} else if (OB_UNLIKELY(is_force_view && 0 == select_item_size)) {
if (OB_FAIL(try_add_error_info(OB_ERR_ONLY_HAVE_INVISIBLE_COL_IN_TABLE, error_info))) {
LOG_WARN("failed to add error info to for force view", K(ret));
@ -577,8 +650,6 @@ int ObCreateViewResolver::check_view_columns(ObSelectStmt &select_stmt,
LOG_TRACE("force view must have at least one column that is not invisible",
K(OB_ERR_ONLY_HAVE_INVISIBLE_COL_IN_TABLE));
}
} else if (OB_FAIL(view_col_names.create(select_item_size))) {
LOG_WARN("failed to init hashset", K(ret), K(select_item_size));
} else if (lib::is_oracle_mode()) {
for (int64_t i = 0; OB_SUCC(ret) && !is_col_dup
&& i < select_stmt.get_select_items().count(); i++) {
@ -1179,6 +1250,58 @@ int ObCreateViewResolver::create_alias_names_auto(
return ret;
}
int ObCreateViewResolver::resolve_mv_options(const ObSelectStmt *stmt,
ParseNode *options_node,
ObMVRefreshInfo &refresh_info,
ObTableSchema &table_schema)
{
int ret = OB_SUCCESS;
refresh_info.refresh_method_ = ObMVRefreshMethod::FORCE; //default method is force
refresh_info.refresh_mode_ = ObMVRefreshMode::DEMAND; //default mode is demand
if (NULL == options_node) {
/* do nothing */
} else if (OB_UNLIKELY(T_MV_OPTIONS != options_node->type_ || 1 != options_node->num_child_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret), K(options_node));
} else if (OB_FAIL(resolve_mv_refresh_info(options_node->children_[0], refresh_info))) {
LOG_WARN("fail to resolve mv refresh info", KR(ret));
} else {
const int64_t on_query_computation_flag = 1;
const int64_t query_rewrite_flag = 1 << 1;
if (options_node->value_ & on_query_computation_flag) {
table_schema.set_mv_on_query_computation(ObMVOnQueryComputationFlag::IS_MV_ON_QUERY_COMPUTATION);
}
if (options_node->value_ & query_rewrite_flag) {
table_schema.set_mv_enable_query_rewrite(ObMVEnableQueryRewriteFlag::IS_MV_ENABLE_QUERY_REWRITE);
}
}
if (OB_FAIL(ret)) {
} else if ((table_schema.mv_on_query_computation() || ObMVRefreshMethod::FAST == refresh_info.refresh_method_)
&& OB_FAIL(ObMVChecker::check_mv_fast_refresh_valid(stmt, params_.stmt_factory_,
params_.expr_factory_,
params_.session_info_))) {
LOG_WARN("fail to check fast refresh valid", K(ret));
} else if (table_schema.mv_on_query_computation()
&& OB_FAIL(check_on_query_computation_supported(stmt))) {
LOG_WARN("fail to check on query computation mv column type", K(ret));
}
return ret;
}
int ObCreateViewResolver::check_on_query_computation_supported(const ObSelectStmt *stmt)
{
int ret = OB_SUCCESS;
ObTransformerImpl::StmtFunc func;
if (OB_FAIL(ObTransformerImpl::check_stmt_functions(stmt, func))) {
LOG_WARN("failed to check stmt functions", K(ret));
} else if (OB_UNLIKELY(func.contain_enum_set_values_)) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "on query computation mview use enum type");
LOG_WARN("not support on query computation mview use enum type", KR(ret), K(func.contain_enum_set_values_));
}
return ret;
}
int ObCreateViewResolver::resolve_mv_refresh_info(ParseNode *refresh_info_node,
ObMVRefreshInfo &refresh_info)
{
@ -1186,9 +1309,6 @@ int ObCreateViewResolver::resolve_mv_refresh_info(ParseNode *refresh_info_node,
if (allocator_ == nullptr) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("allocator_ is null", KR(ret));
} else {
refresh_info.refresh_method_ = ObMVRefreshMethod::FORCE; //default method is force
refresh_info.refresh_mode_ = ObMVRefreshMode::DEMAND; //default mode is demand
}
char buf[OB_MAX_PROC_ENV_LENGTH];
int64_t pos = 0;
@ -1309,9 +1429,11 @@ int ObCreateViewResolver::resolve_mv_refresh_info(ParseNode *refresh_info_node,
}
int ObCreateViewResolver::resolve_column_list(ParseNode *view_columns_node,
ObIArray<ObString> &column_list)
ObIArray<ObString> &column_list,
ParseNode *&mv_primary_key_node)
{
int ret = OB_SUCCESS;
mv_primary_key_node = NULL;
if (OB_ISNULL(allocator_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("allocator_ is NULL", K(ret));
@ -1326,6 +1448,13 @@ int ObCreateViewResolver::resolve_column_list(ParseNode *view_columns_node,
if (OB_ISNULL(column_node)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("column node should not be NULL", K(ret));
} else if (T_PRIMARY_KEY == column_node->type_) {
if (OB_UNLIKELY(NULL != mv_primary_key_node)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("more than one primary key node", K(ret));
} else {
mv_primary_key_node = column_node;
}
} else {
column.reset();
ObString column_name;

View File

@ -92,7 +92,12 @@ private:
int check_privilege(ObCreateTableStmt *stmt,
ObSelectStmt *select_stmt);
int resolve_column_list(ParseNode *view_columns_node,
common::ObIArray<common::ObString> &column_list);
common::ObIArray<common::ObString> &column_list,
ParseNode *&mv_primary_key_node);
int resolve_mv_options(const ObSelectStmt *stmt,
ParseNode *options_node,
ObMVRefreshInfo &refresh_info,
ObTableSchema &table_schema);
int resolve_mv_refresh_info(ParseNode *refresh_info_node,
ObMVRefreshInfo &refresh_info);
@ -132,7 +137,12 @@ private:
hash::ObHashMap<int64_t, const TableItem *> &select_tables,
hash::ObHashMap<int64_t, const TableItem *> &any_tables);
int add_hidden_tablet_seq_col(ObTableSchema &table_schema);
int resolve_materialized_view_container_table(ParseNode *partition_node,
ParseNode *mv_primary_key_node,
ObTableSchema &container_table_schema,
ObSEArray<ObConstraint,4>& csts);
int resolve_primary_key_node(ParseNode &pk_node, ObTableSchema &table_schema);
int check_on_query_computation_supported(const ObSelectStmt *stmt);
private:
DISALLOW_COPY_AND_ASSIGN(ObCreateViewResolver);
};

View File

@ -5577,32 +5577,26 @@ int ObDMLResolver::resolve_base_or_alias_table_item_normal(uint64_t tenant_id,
//the feature only use in mysqtest case, not open for user
const ObTableSchema *tab_schema = NULL;
item->is_index_table_ = tschema->is_index_table();
if (tschema->is_materialized_view()) {
item->ref_id_ = tschema->get_data_table_id();
item->table_type_ = tschema->get_table_type();
} else {
item->ref_id_ = tschema->get_table_id();
}
item->table_id_ = generate_table_id();
item->type_ = TableItem::ALIAS_TABLE;
//主表schema
if (OB_FAIL(schema_checker_->get_table_schema(session_info_->get_effective_tenant_id(), tschema->get_data_table_id(), tab_schema))) {
LOG_WARN("get data table schema failed", K(ret), K_(item->ref_id));
} else {
item->table_name_ = tab_schema->get_table_name_str(); //主表的名字
if (alias_name.length() == 0) {
if (tschema->is_materialized_view()) {
if (!synonym_name.empty()) {
item->alias_name_ = synonym_name; //mv可能有同义词,需要考虑同义词
} else {
item->alias_name_ = tschema->get_table_name_str(); //将mv作为主表的alias name
}
} else {
item->alias_name_ = tschema->get_table_name_str(); //将索引名作为主表的alias name
}
if (tschema->is_materialized_view()) {
item->ref_id_ = tschema->get_data_table_id();
item->mview_id_ = tschema->get_table_id();
item->table_type_ = tschema->get_table_type();
item->need_expand_rt_mv_ = !params_.is_for_rt_mv_ && tschema->mv_on_query_computation();
item->table_name_ = tschema->get_table_name_str();
item->alias_name_ = alias_name.empty() ? tschema->get_table_name_str() : alias_name;
LOG_DEBUG("resolve mv table", K(ret), K(tschema->get_table_name()), K(params_.is_for_rt_mv_),
K(tschema->mv_enable_query_rewrite()), K(tschema->mv_on_query_computation()));
} else {
item->alias_name_ = alias_name;
item->ref_id_ = tschema->get_table_id();
item->table_name_ = tab_schema->get_table_name_str(); //主表的名字
//将索引名作为主表的alias name
item->alias_name_ = alias_name.empty() ? tschema->get_table_name_str() : alias_name;
}
//如果是查索引表,需要将主表的依赖也要加入到plan中
ObSchemaObjVersion table_version;
@ -14210,7 +14204,14 @@ int ObDMLResolver::resolve_transform_hint(const ParseNode &hint_node,
case T_PLACE_GROUP_BY:
case T_NO_PLACE_GROUP_BY: {
if (OB_FAIL(resolve_place_group_by_hint(hint_node, trans_hint))) {
LOG_WARN("failed to resolve win magic hint", K(ret));
LOG_WARN("failed to resolve place group by hint", K(ret));
}
break;
}
case T_MV_REWRITE:
case T_MV_NO_REWRITE: {
if (OB_FAIL(resolve_mv_rewrite_hint(hint_node, trans_hint))) {
LOG_WARN("failed to resolve mv rewrite hint", K(ret));
}
break;
}
@ -15126,6 +15127,32 @@ int ObDMLResolver::resolve_place_group_by_hint(const ParseNode &hint_node,
return ret;
}
int ObDMLResolver::resolve_mv_rewrite_hint(const ParseNode &hint_node,
ObTransHint *&hint)
{
int ret = OB_SUCCESS;
hint = NULL;
ObMVRewriteHint *mv_rewrite_hint = NULL;
ObString qb_name;
if (OB_UNLIKELY(1 != hint_node.num_child_ && 2 != hint_node.num_child_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected mv rewrite hint", K(ret), K(hint_node.num_child_));
} else if (OB_FAIL(ObQueryHint::create_hint(allocator_, hint_node.type_, mv_rewrite_hint))) {
LOG_WARN("failed to create eliminate join hint", K(ret));
} else if (OB_FAIL(resolve_qb_name_node(hint_node.children_[0], qb_name))) {
LOG_WARN("Failed to resolve qb name node", K(ret));
} else if (2 == hint_node.num_child_ && NULL != hint_node.children_[1] &&
OB_FAIL(resolve_simple_table_list_in_hint(hint_node.children_[1],
mv_rewrite_hint->get_mv_list()))) {
LOG_WARN("failed to resovle simple table list in hint", K(ret));
} else {
mv_rewrite_hint->set_qb_name(qb_name);
hint = mv_rewrite_hint;
LOG_DEBUG("show mv_rewrite_hint hint", KPC(mv_rewrite_hint));
}
return ret;
}
int ObDMLResolver::resolve_tb_name_list(const ParseNode *tb_name_list_node,
ObIArray<ObSEArray<ObTableInHint, 4>> &tb_name_list)
{

View File

@ -924,6 +924,7 @@ private:
int resolve_eliminate_join_hint(const ParseNode &hint_node, ObTransHint *&hint);
int resolve_win_magic_hint(const ParseNode &hint_node, ObTransHint *&hint);
int resolve_place_group_by_hint(const ParseNode &hint_node, ObTransHint *&hint);
int resolve_mv_rewrite_hint(const ParseNode &hint_node, ObTransHint *&hint);
int resolve_tb_name_list(const ParseNode *tb_name_list_node, ObIArray<ObSEArray<ObTableInHint, 4>> &tb_name_list);
int resolve_alloc_ops(const ParseNode &alloc_op_node, ObIArray<ObAllocOpHint> &alloc_op_hints);
int resolve_tables_in_leading_hint(const ParseNode *tables_node, ObLeadingTable &leading_table);

View File

@ -256,7 +256,8 @@ int TableItem::deep_copy(ObIRawExprCopier &expr_copier,
for_update_ = other.for_update_;
for_update_wait_us_ = other.for_update_wait_us_;
skip_locked_ = other.skip_locked_;
mock_id_ = other.mock_id_;
need_expand_rt_mv_ = other.need_expand_rt_mv_;
mview_id_ = other.mview_id_;
node_ = other.node_; // should deep copy ? seems to be unnecessary
flashback_query_type_ = other.flashback_query_type_;
// dblink
@ -1836,7 +1837,8 @@ int ObDMLStmt::formalize_relation_exprs(ObSQLSessionInfo *session_info)
}
int ObDMLStmt::formalize_stmt_expr_reference(ObRawExprFactory *expr_factory,
ObSQLSessionInfo *session_info)
ObSQLSessionInfo *session_info,
bool explicit_for_col /* default false */)
{
int ret = OB_SUCCESS;
ObSEArray<ObRawExpr*, 32> stmt_exprs;
@ -1892,7 +1894,7 @@ int ObDMLStmt::formalize_stmt_expr_reference(ObRawExprFactory *expr_factory,
} else { /*do nothing*/ }
}
if (OB_SUCC(ret)) {
if (OB_FAIL(remove_useless_sharable_expr(expr_factory, session_info))) {
if (OB_FAIL(remove_useless_sharable_expr(expr_factory, session_info, explicit_for_col))) {
LOG_WARN("failed to remove useless sharable expr", K(ret));
} else if (OB_FAIL(check_pseudo_column_valid())) {
LOG_WARN("failed to check pseudo column", K(ret));
@ -2081,37 +2083,41 @@ int ObDMLStmt::generated_column_depend_column_is_referred(ObRawExpr *expr, bool
}
int ObDMLStmt::remove_useless_sharable_expr(ObRawExprFactory *expr_factory,
ObSQLSessionInfo *session_info)
ObSQLSessionInfo *session_info,
bool explicit_for_col)
{
int ret = OB_SUCCESS;
UNUSED(expr_factory);
UNUSED(session_info);
for (int64_t i = column_items_.count() - 1; OB_SUCC(ret) && i >= 0; i--) {
ObColumnRefRawExpr *expr = NULL;
bool is_referred = false;
bool need_remove = false;
if (OB_ISNULL(expr = column_items_.at(i).expr_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (expr->is_explicited_reference() || expr->is_rowkey_column()
|| expr->is_spatial_generated_column()) {
/*do nothing*/
} else if (expr->is_explicited_reference()) {
need_remove = false;
} else if (explicit_for_col) {
need_remove = true;
} else if (expr->is_rowkey_column() || expr->is_spatial_generated_column()) {
need_remove = false;
} else if (OB_FAIL(is_referred_by_partitioning_expr(expr, is_referred))) {
LOG_WARN("failed to check whether is referred by partitioning expr", K(ret));
} else if (is_referred) {
need_remove = false;
} else if (OB_FAIL(generated_column_depend_column_is_referred(expr, is_referred))) {
//if the generate column's depend expr has columns referred.
LOG_WARN("generated expr has normal column depends", K(ret));
} else {
bool is_referred = true;
if (OB_FAIL(is_referred_by_partitioning_expr(expr, is_referred))) {
LOG_WARN("failed to check whether is referred by partitioning expr", K(ret));
}
need_remove = !is_referred;
}
if (OB_FAIL(ret) || is_referred) {
//if the generate column's depend expr has columns referred.
} else if (OB_FAIL(generated_column_depend_column_is_referred(expr, is_referred))) {
LOG_WARN("generated expr has normal column depends", K(ret));
}
if (OB_SUCC(ret) && !is_referred) {
if (OB_FAIL(column_items_.remove(i))) {
LOG_WARN("failed to remove column item", K(ret));
} else {
LOG_TRACE("succeed to remove column items", K(expr), K(lbt()));
}
if (OB_SUCC(ret) && need_remove) {
if (OB_FAIL(column_items_.remove(i))) {
LOG_WARN("failed to remove column item", K(ret));
} else {
LOG_TRACE("succeed to remove column items", K(expr), K(lbt()));
}
}
}
@ -4630,14 +4636,14 @@ int ObDMLStmt::disable_writing_external_table(bool basic_stmt_is_dml /* defualt
return ret;
}
int ObDMLStmt::disable_writing_materialized_view()
int ObDMLStmt::disable_writing_materialized_view() const
{
int ret = OB_SUCCESS;
bool disable_write_table = false;
const TableItem *table_item = NULL;
if (is_dml_write_stmt()) {
ObSEArray<ObDmlTableInfo*, 4> dml_table_infos;
if (OB_FAIL(static_cast<ObDelUpdStmt*>(this)->get_dml_table_infos(dml_table_infos))) {
ObSEArray<const ObDmlTableInfo*, 4> dml_table_infos;
if (OB_FAIL(static_cast<const ObDelUpdStmt*>(this)->get_dml_table_infos(dml_table_infos))) {
LOG_WARN("failed to get dml table infos");
}
for (int64_t i = 0; OB_SUCC(ret) && !disable_write_table && i < dml_table_infos.count(); ++i) {

View File

@ -227,7 +227,8 @@ struct TableItem
for_update_ = false;
for_update_wait_us_ = -1;
skip_locked_ = false;
mock_id_ = common::OB_INVALID_ID;
need_expand_rt_mv_ = false;
mview_id_ = common::OB_INVALID_ID;
node_ = NULL;
view_base_item_ = NULL;
flashback_query_expr_ = nullptr;
@ -254,7 +255,6 @@ struct TableItem
N_FOR_UPDATE, for_update_,
N_WAIT, for_update_wait_us_,
K_(skip_locked),
N_MOCK_ID, mock_id_,
"view_base_item",
(NULL == view_base_item_ ? OB_INVALID_ID : view_base_item_->table_id_),
K_(dblink_id), K_(dblink_name), K_(link_database_name), K_(is_reverse_link),
@ -262,8 +262,7 @@ struct TableItem
K_(is_view_table), K_(part_ids), K_(part_names), K_(cte_type),
KPC_(function_table_expr),
K_(flashback_query_type), KPC_(flashback_query_expr), K_(table_type),
K(table_values_),
K_(exec_params));
K(table_values_), K_(exec_params), K_(mview_id), K_(need_expand_rt_mv));
enum TableType
{
@ -381,8 +380,8 @@ struct TableItem
bool for_update_;
int64_t for_update_wait_us_;//0 means nowait, -1 means infinite
bool skip_locked_;
//在hierarchical query, 记录由当前table_item mock出来的table_item的table id
uint64_t mock_id_;
bool need_expand_rt_mv_; // for real-time materialized view
uint64_t mview_id_; // for materialized view, ref_id_ is mv container table id, mview_id_ is the view id
const ParseNode* node_;
// base table item for updatable view
const TableItem *view_base_item_; // seems to be useful only in the resolve phase
@ -821,14 +820,17 @@ public:
int pull_all_expr_relation_id();
int formalize_stmt(ObSQLSessionInfo *session_info);
int formalize_relation_exprs(ObSQLSessionInfo *session_info);
int formalize_stmt_expr_reference(ObRawExprFactory *expr_factory, ObSQLSessionInfo *session_info);
int formalize_stmt_expr_reference(ObRawExprFactory *expr_factory,
ObSQLSessionInfo *session_info,
bool explicit_for_col = false);
int formalize_child_stmt_expr_reference(ObRawExprFactory *expr_factory,
ObSQLSessionInfo *session_info);
int set_sharable_expr_reference(ObRawExpr &expr, ExplicitedRefType ref_type);
int check_pseudo_column_valid();
int get_ora_rowscn_column(const uint64_t table_id, ObPseudoColumnRawExpr *&ora_rowscn);
virtual int remove_useless_sharable_expr(ObRawExprFactory *expr_factory,
ObSQLSessionInfo *session_info);
ObSQLSessionInfo *session_info,
bool explicit_for_col);
virtual int clear_sharable_expr_reference();
virtual int get_from_subquery_stmts(common::ObIArray<ObSelectStmt*> &child_stmts) const;
virtual int get_subquery_stmts(common::ObIArray<ObSelectStmt*> &child_stmts) const;
@ -1163,7 +1165,7 @@ public:
int check_has_subquery_in_function_table(bool &has_subquery_in_function_table) const;
int disable_writing_external_table(bool basic_stmt_is_dml = false);
int disable_writing_materialized_view();
int disable_writing_materialized_view() const;
int formalize_query_ref_exprs();
int formalize_query_ref_exec_params(ObStmtExecParamFormatter &formatter,
@ -1178,6 +1180,10 @@ public:
int do_formalize_lateral_derived_table_pre();
int deep_copy_join_tables(ObIAllocator &allocator,
ObIRawExprCopier &expr_copier,
const ObDMLStmt &other);
int do_formalize_lateral_derived_table_post();
protected:
@ -1185,9 +1191,6 @@ protected:
//获取到stmt中所有查询相关的表达式(由查询语句中指定的属性生成的表达式)的root expr
protected:
int deep_copy_join_tables(ObIAllocator &allocator,
ObIRawExprCopier &expr_copier,
const ObDMLStmt &other);
int construct_join_table(const ObDMLStmt &other,
const JoinedTable &other_joined_table,
JoinedTable &joined_table);

View File

@ -974,6 +974,7 @@ ObItemType ObHint::get_hint_type(ObItemType type)
case T_NO_AGGR_FIRST_UNNEST: return T_AGGR_FIRST_UNNEST;
case T_NO_JOIN_FIRST_UNNEST: return T_JOIN_FIRST_UNNEST;
case T_NO_DECORRELATE : return T_DECORRELATE;
case T_MV_NO_REWRITE: return T_MV_REWRITE;
// optimize hint
case T_NO_USE_DAS_HINT: return T_USE_DAS_HINT;
@ -1031,6 +1032,7 @@ const char* ObHint::get_hint_name(ObItemType type, bool is_enable_hint /* defaul
case T_AGGR_FIRST_UNNEST: return is_enable_hint ? "AGGR_FIRST_UNNEST" : "NO_AGGR_FIRST_UNNEST";
case T_JOIN_FIRST_UNNEST: return is_enable_hint ? "JOIN_FIRST_UNNEST" : "NO_JOIN_FIRST_UNNEST";
case T_DECORRELATE : return is_enable_hint ? "DECORRELATE" : "NO_DECORRELATE";
case T_MV_REWRITE: return is_enable_hint ? "MV_REWRITE" : "NO_MV_REWRITE";
// optimize hint
case T_INDEX_HINT: return "INDEX";
case T_FULL_HINT: return "FULL";
@ -1908,6 +1910,56 @@ bool ObCoalesceSqHint::has_qb_name_list(const ObIArray<ObString> & qb_names) con
return bret;
}
int ObMVRewriteHint::assign(const ObMVRewriteHint &other)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObTransHint::assign(other))) {
LOG_WARN("fail to assign hint", K(ret));
} else if (OB_FAIL(mv_list_.assign(other.mv_list_))) {
LOG_WARN("failed to assign mv list", K(ret));
}
return ret;
}
int ObMVRewriteHint::print_hint_desc(PlanText &plan_text) const
{
int ret = OB_SUCCESS;
if (!mv_list_.empty()) {
char *buf = plan_text.buf_;
int64_t &buf_len = plan_text.buf_len_;
int64_t &pos = plan_text.pos_;
for (int64_t i = 0; OB_SUCC(ret) && i < mv_list_.count(); ++i) {
if (i > 0 && OB_FAIL(BUF_PRINTF(", "))) {
LOG_WARN("fail to print comma", K(ret));
} else if (OB_FAIL(mv_list_.at(i).print_table_in_hint(plan_text, true))) {
LOG_WARN("fail to print mv table", K(ret));
}
}
}
return ret;
}
int ObMVRewriteHint::check_mv_match_hint(ObCollationType cs_type,
const ObTableSchema *mv_schema,
const ObDatabaseSchema *db_schema,
bool &is_match) const
{
int ret = OB_SUCCESS;
is_match = false;
if (OB_ISNULL(mv_schema) || OB_ISNULL(db_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret), K(mv_schema), K(db_schema));
} else if (mv_list_.empty()) {
is_match = true;
}
for (int64_t i = 0; OB_SUCC(ret) && !is_match && i < mv_list_.count(); ++i) {
const ObTableInHint &table_in_hint = mv_list_.at(i);
is_match = 0 == ObCharset::strcmp(cs_type, table_in_hint.table_name_, mv_schema->get_table_name()) &&
(table_in_hint.db_name_.empty() || 0 == ObCharset::strcmp(cs_type, table_in_hint.db_name_, db_schema->get_database_name_str()));
}
return ret;
}
int ObTableParallelHint::assign(const ObTableParallelHint &other)
{
int ret = OB_SUCCESS;

View File

@ -439,6 +439,7 @@ public:
HINT_ELIMINATE_JOIN,
HINT_GROUPBY_PLACEMENT,
HINT_WIN_MAGIC,
HINT_MV_REWRITE,
// optimize hint below
HINT_OPTIMIZE, // normal optimize hint
HINT_ACCESS_PATH,
@ -815,6 +816,32 @@ private:
common::ObSEArray<QbNameList, 2, common::ModulePageAllocator, true> qb_name_list_;
};
class ObMVRewriteHint : public ObTransHint
{
public:
ObMVRewriteHint(ObItemType hint_type)
: ObTransHint(hint_type),
mv_list_()
{
set_hint_class(HINT_MV_REWRITE);
}
int assign(const ObMVRewriteHint &other);
virtual ~ObMVRewriteHint() {}
virtual int print_hint_desc(PlanText &plan_text) const override;
common::ObIArray<ObTableInHint> &get_mv_list() { return mv_list_; }
const common::ObIArray<ObTableInHint> &get_mv_list() const { return mv_list_; }
int check_mv_match_hint(ObCollationType cs_type,
const ObTableSchema *mv_schema,
const ObDatabaseSchema *db_schema,
bool &is_match) const;
INHERIT_TO_STRING_KV("ObHint", ObHint, K_(mv_list));
private:
common::ObSEArray<ObTableInHint, 1, common::ModulePageAllocator, true> mv_list_;
};
class ObIndexHint : public ObOptHint
{
public:

View File

@ -156,11 +156,11 @@ int ObSelectStmt::check_aggr_and_winfunc(ObRawExpr &expr)
if (expr.is_aggr_expr() &&
!ObRawExprUtils::find_expr(agg_items_, &expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("aggr expr does not exist in the stmt", K(ret));
LOG_WARN("aggr expr does not exist in the stmt", K(ret), K(expr));
} else if (expr.is_win_func_expr() &&
!ObRawExprUtils::find_expr(win_func_exprs_, &expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("win func expr does not exist in the stmt", K(ret));
LOG_WARN("win func expr does not exist in the stmt", K(ret), K(expr));
}
return ret;
}
@ -229,6 +229,7 @@ int ObSelectStmt::assign(const ObSelectStmt &other)
is_hierarchical_query_ = other.is_hierarchical_query_;
has_prior_ = other.has_prior_;
has_reverse_link_ = other.has_reverse_link_;
is_expanded_mview_ = other.is_expanded_mview_;
}
return ret;
}
@ -320,6 +321,7 @@ int ObSelectStmt::deep_copy_stmt_struct(ObIAllocator &allocator,
is_hierarchical_query_ = other.is_hierarchical_query_;
has_prior_ = other.has_prior_;
has_reverse_link_ = other.has_reverse_link_;
is_expanded_mview_ = other.is_expanded_mview_;
// copy insert into statement
if (OB_SUCC(ret) && NULL != other.into_item_) {
ObSelectIntoItem *temp_into_item = NULL;
@ -530,6 +532,7 @@ ObSelectStmt::ObSelectStmt()
is_hierarchical_query_ = false;
has_prior_ = false;
has_reverse_link_ = false;
is_expanded_mview_ = false;
}
ObSelectStmt::~ObSelectStmt()
@ -725,7 +728,8 @@ int ObSelectStmt::do_to_string(char *buf, const int64_t buf_len, int64_t &pos) c
K_(is_hierarchical_query),
K_(check_option),
K_(dblink_id),
K_(is_reverse_link)
K_(is_reverse_link),
K_(is_expanded_mview)
);
}
} else {
@ -833,13 +837,14 @@ int ObSelectStmt::clear_sharable_expr_reference()
}
int ObSelectStmt::remove_useless_sharable_expr(ObRawExprFactory *expr_factory,
ObSQLSessionInfo *session_info)
ObSQLSessionInfo *session_info,
bool explicit_for_col)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(expr_factory)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(ret));
} else if (OB_FAIL(ObDMLStmt::remove_useless_sharable_expr(expr_factory, session_info))) {
} else if (OB_FAIL(ObDMLStmt::remove_useless_sharable_expr(expr_factory, session_info, explicit_for_col))) {
LOG_WARN("failed to remove useless sharable expr", K(ret));
} else {
ObRawExpr *expr = NULL;

View File

@ -429,6 +429,8 @@ public:
bool is_order_siblings() const { return is_order_siblings_; }
void set_hierarchical_query(bool is_hierarchical_query) { is_hierarchical_query_ = is_hierarchical_query; }
bool is_hierarchical_query() const { return is_hierarchical_query_; }
inline void set_expanded_mview(bool is_expanded_mview) { is_expanded_mview_ = is_expanded_mview; }
inline bool is_expanded_mview() const { return is_expanded_mview_; }
int contain_hierarchical_query(bool &contain_hie_query) const;
void set_has_prior(bool has_prior) { has_prior_ = has_prior; }
bool has_prior() const { return has_prior_; }
@ -454,7 +456,8 @@ public:
bool has_hidden_rowid() const;
virtual int clear_sharable_expr_reference() override;
virtual int remove_useless_sharable_expr(ObRawExprFactory *expr_factory,
ObSQLSessionInfo *session_info) override;
ObSQLSessionInfo *session_info,
bool explicit_for_col) override;
const common::ObIArray<OrderItem>& get_search_by_items() const { return search_by_items_; }
const common::ObIArray<ColumnItem>& get_cycle_items() const { return cycle_by_items_; }
@ -707,6 +710,7 @@ private:
bool is_hierarchical_query_;
bool has_prior_;
bool has_reverse_link_;
bool is_expanded_mview_;
};
}
}

View File

@ -39,6 +39,9 @@ void ObQueryHint::reset()
used_trans_hints_.reuse();
qb_name_map_.reuse();
stmt_id_map_.reuse();
sel_start_id_ = 1;
set_start_id_ = 1;
other_start_id_ = 1;
}
int ObQueryHint::create_hint_table(ObIAllocator *allocator, ObTableInHint *&table)
@ -313,7 +316,7 @@ int ObQueryHint::init_query_hint(ObIAllocator *allocator,
LOG_WARN("failed to create qb name map", K(ret));
} else if (OB_FAIL(reset_duplicate_qb_name())) {
LOG_WARN("failed to reset duplicate qb name", K(ret));
} else if (OB_FAIL(generate_orig_stmt_qb_name(*allocator))) {
} else if (OB_FAIL(generate_orig_stmt_qb_name(*allocator, 0))) {
LOG_WARN("failed to generate stmt name after resolve", K(ret));
} else if (OB_FAIL(distribute_hint_to_orig_stmt(stmt))) {
LOG_WARN("faild to distribute hint to orig stmt", K(ret));
@ -387,17 +390,13 @@ int ObQueryHint::adjust_qb_name_for_stmt(ObIAllocator &allocator,
return ret;
}
int ObQueryHint::generate_orig_stmt_qb_name(ObIAllocator &allocator)
int ObQueryHint::generate_orig_stmt_qb_name(ObIAllocator &allocator, int64_t inited_stmt_count)
{
int ret = OB_SUCCESS;
int64_t sel_start_id = 1;
int64_t set_start_id = 1;
int64_t other_start_id = 1;
char buf[OB_MAX_QB_NAME_LENGTH];
int64_t buf_len = OB_MAX_QB_NAME_LENGTH;
ObString qb_name;
qb_name_map_.reuse();
for (int64_t idx = 0; OB_SUCC(ret) && idx < stmt_id_map_.count(); ++idx) {
for (int64_t idx = inited_stmt_count; OB_SUCC(ret) && idx < stmt_id_map_.count(); ++idx) {
QbNames &qb_names = stmt_id_map_.at(idx);
const char *stmt_name = get_dml_stmt_name(qb_names.stmt_type_, qb_names.is_set_stmt_);
int64_t pos = 0;
@ -415,8 +414,8 @@ int ObQueryHint::generate_orig_stmt_qb_name(ObIAllocator &allocator)
LOG_WARN("failed print buf stmt_name", K(ret));
} else {
int64_t &id_start = stmt::T_SELECT == qb_names.stmt_type_
? (qb_names.is_set_stmt_ ? set_start_id : sel_start_id)
: other_start_id;
? (qb_names.is_set_stmt_ ? set_start_id_ : sel_start_id_)
: other_start_id_;
int64_t old_pos = pos;
int64_t cnt = 0;
qb_name.reset();

View File

@ -94,7 +94,7 @@ struct ObQueryHint {
const ObIArray<uint32_t> &src_hash_val,
int64_t *sub_num = NULL);
int generate_orig_stmt_qb_name(ObIAllocator &allocator);
int generate_orig_stmt_qb_name(ObIAllocator &allocator, int64_t inited_stmt_count);
int generate_qb_name_for_stmt(ObIAllocator &allocator,
const ObDMLStmt &stmt,
const ObString &src_qb_name,
@ -172,6 +172,9 @@ struct ObQueryHint {
ObSEArray<const ObHint*, 8, common::ModulePageAllocator, true> used_trans_hints_;
ObSEArray<QbNames, 8, common::ModulePageAllocator, true> stmt_id_map_; // stmt id -> qb name list, position is stmt id
hash::ObHashMap<ObString, int64_t> qb_name_map_; // qb name -> stmt id
int64_t sel_start_id_;
int64_t set_start_id_;
int64_t other_start_id_;
private:
DISALLOW_COPY_AND_ASSIGN(ObQueryHint);

View File

@ -834,6 +834,7 @@ int ObRawExpr::is_const_inherit_expr(bool &is_const_inherit,
|| (param_need_replace ? is_not_calculable_expr() : cnt_not_calculable_expr())
|| T_FUN_LABEL_SE_SESSION_LABEL == type_
|| T_FUN_LABEL_SE_SESSION_ROW_LABEL == type_
|| T_FUN_SYS_LAST_REFRESH_SCN == type_
|| (T_FUN_UDF == type_
&& !static_cast<const ObUDFRawExpr*>(this)->is_deterministic())
|| T_FUN_SYS_GET_LOCK == type_
@ -4007,6 +4008,8 @@ bool ObSysFunRawExpr::inner_same_as(
T_OP_GET_SYS_VAR == get_expr_type() ||
(has_flag(IS_STATE_FUNC) && (NULL == check_context ||
(NULL != check_context && check_context->need_check_deterministic_)))) {
} else if (T_FUN_SYS_LAST_REFRESH_SCN == get_expr_type()) {
bool_ret = get_mview_id() == static_cast<const ObSysFunRawExpr&>(expr).get_mview_id();
} else if (get_expr_class() == expr.get_expr_class()) {
//for EXPR_UDF and EXPR_SYS_FUNC
const ObSysFunRawExpr *s_expr = static_cast<const ObSysFunRawExpr *>(&expr);
@ -4277,6 +4280,10 @@ int ObSysFunRawExpr::get_name_internal(char *buf, const int64_t buf_len, int64_t
} else if (T_FUN_SYS_INNER_ROW_CMP_VALUE == get_expr_type()) {
CK(3 == get_param_count());
OZ(get_param_expr(2)->get_name(buf, buf_len, pos, type));
} else if (T_FUN_SYS_LAST_REFRESH_SCN == get_expr_type()) {
if (OB_FAIL(BUF_PRINTF("%ld", get_mview_id()))) {
LOG_WARN("fail to BUF_PRINTF", K(ret));
}
} else {
int64_t i = 0;
if (get_param_count() > 1) {

View File

@ -3556,6 +3556,8 @@ public:
int get_autoinc_nextval_name(char *buf, int64_t buf_len, int64_t &pos) const;
void set_op_id(int64_t operator_id) { operator_id_ = operator_id; }
int64_t get_op_id() const { return operator_id_; }
void set_mview_id(uint64_t mview_id) { mview_id_ = mview_id; }
uint64_t get_mview_id() const { return mview_id_; }
void set_dblink_name(const common::ObString &name) { dblink_name_ = name; }
const common::ObString &get_dblink_name() const { return dblink_name_; }
void set_dblink_id(int64_t dblink_id) { dblink_id_ = dblink_id; }
@ -3572,7 +3574,8 @@ public:
K_(dblink_name),
K_(dblink_id),
K_(local_session_var),
K_(local_session_var_id));
K_(local_session_var_id),
K_(mview_id));
virtual int set_local_session_vars(const share::schema::ObLocalSessionVar *local_sys_vars,
const ObBasicSessionInfo *session,
int64_t ctx_array_idx);
@ -3581,8 +3584,10 @@ private:
DISALLOW_COPY_AND_ASSIGN(ObSysFunRawExpr);
common::ObString func_name_;
common::ObString dblink_name_;
//用于记录rownum表达式归属的count算子的op_id_
uint64_t operator_id_;
union {
uint64_t operator_id_; // for rownum expr
uint64_t mview_id_; // for last_refresh_scn expr
};
uint64_t dblink_id_;
};

View File

@ -202,13 +202,23 @@ int ObRawExprCopier::add_expr(const ObRawExpr *from,
LOG_WARN("failed to create expr set", K(ret));
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(copied_exprs_.set_refactored(reinterpret_cast<uint64_t>(from),
reinterpret_cast<uint64_t>(to)))) {
if (OB_FAIL(ret)) {
} else if (OB_SUCCESS != (ret = copied_exprs_.set_refactored(reinterpret_cast<uint64_t>(from),
reinterpret_cast<uint64_t>(to)))) {
if (OB_UNLIKELY(ret != OB_HASH_EXIST)) {
LOG_WARN("faield to add copied expr into map", K(ret));
} else if (OB_FAIL(new_exprs_.set_refactored(reinterpret_cast<uint64_t>(to)))) {
LOG_WARN("failed to add copied expr into set", K(ret));
} else {
ret = OB_SUCCESS;
uint64_t val = 0;
if (OB_FAIL(copied_exprs_.get_refactored(reinterpret_cast<uint64_t>(from), val))) {
LOG_WARN("get expr from hash map failed", K(ret));
} else if (OB_UNLIKELY(val != reinterpret_cast<uint64_t>(to))) {
ret = OB_HASH_EXIST;
LOG_WARN("from expr exists", K(ret), KPC(from), KPC(to), K(val));
}
}
} else if (OB_FAIL(new_exprs_.set_refactored(reinterpret_cast<uint64_t>(to)))) {
LOG_WARN("failed to add copied expr into set", K(ret));
}
return ret;
}

View File

@ -480,6 +480,7 @@ int ObRawExprInfoExtractor::visit(ObSysFunRawExpr &expr)
|| (T_FUN_SYS_SYSDATE == expr.get_expr_type() && !lib::is_oracle_mode())
|| T_FUN_NORMAL_UDF == expr.get_expr_type()
|| T_FUN_SYS_GENERATOR == expr.get_expr_type()
|| T_FUN_SYS_LAST_REFRESH_SCN == expr.get_expr_type()
|| (T_FUN_UDF == expr.get_expr_type()
&& !static_cast<ObUDFRawExpr&>(expr).is_deterministic())
|| T_FUN_SYS_GET_LOCK == expr.get_expr_type()

View File

@ -1195,6 +1195,12 @@ int ObRawExprResolverImpl::do_recursive_resolve(const ParseNode *node, ObRawExpr
}
break;
}
case T_FUN_SYS_LAST_REFRESH_SCN: {
if (OB_FAIL(process_last_refresh_scn_node(node, expr))) {
LOG_WARN("failed to process last refresh scn node", K(ret));
}
break;
}
case T_DBLINK_UDF: {
if (OB_FAIL(process_dblink_udf_node(node, expr))) {
LOG_WARN("failed to process dblink udf node", K(ret), K(node));
@ -8353,6 +8359,69 @@ int ObRawExprResolverImpl::process_odbc_time_literals(const ObItemType dst_time_
return ret;
}
int ObRawExprResolverImpl::process_last_refresh_scn_node(const ParseNode *expr_node,
ObRawExpr *&expr)
{
int ret = OB_SUCCESS;
expr = NULL;
const ParseNode *child_node = NULL;
ObSysFunRawExpr *func_expr = NULL;
uint64_t mview_id = OB_INVALID_ID;
if (OB_ISNULL(expr_node) || OB_UNLIKELY(1 != expr_node->num_child_)
|| OB_ISNULL(child_node = expr_node->children_[0])) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret), K(expr_node), K(child_node));
} else if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS_LAST_REFRESH_SCN, func_expr))) {
LOG_WARN("fail to create raw expr", K(ret));
} else if (OB_ISNULL(func_expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("func_expr is null");
} else if (T_INT == child_node->type_) {
mview_id = static_cast<uint64_t>(child_node->value_);
} else if (OB_UNLIKELY(T_QUESTIONMARK != child_node->type_)
|| OB_ISNULL(ctx_.query_ctx_) || OB_ISNULL(ctx_.param_list_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected params", K(ret), K(get_type_name(child_node->type_)), K(ctx_.query_ctx_), K(ctx_.param_list_));
} else { // question mark need add const constaint.
ObPCConstParamInfo const_param_info;
const int64_t idx = child_node->value_;
const ObObj &val = ctx_.param_list_->at(idx);
number::ObNumber number;
if (val.is_integer_type()) {
mview_id = static_cast<uint64_t>(val.get_int());
} else if (val.is_decimal_int()) {
bool is_valid = false;
if (OB_FAIL(wide::check_range_valid_uint64(val.get_decimal_int(), val.get_int_bytes(),
is_valid, mview_id))) {
LOG_WARN("check_range_valid_uint64 failed", K(ret), K(val.get_int_bytes()));
} else if (OB_UNLIKELY(!is_valid)) {
ret = OB_OBJ_TYPE_ERROR;
LOG_WARN("failed to get uint64", K(ret), K(val));
}
} else if (OB_FAIL(val.get_number(number))) {
LOG_WARN("failed to get number", K(ret), K(val.get_meta()), K(val));
} else if (OB_UNLIKELY(!number.is_valid_uint64(mview_id))) {
ret = OB_OBJ_TYPE_ERROR;
LOG_WARN("failed to get uint64", K(ret), K(number));
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(const_param_info.const_idx_.push_back(idx))
|| OB_FAIL(const_param_info.const_params_.push_back(val))) {
LOG_WARN("failed to push back param idx and value", K(ret));
} else if (OB_FAIL(ctx_.query_ctx_->all_plan_const_param_constraints_.push_back(const_param_info))) {
LOG_WARN("failed to push back const param info", K(ret));
}
}
if (OB_SUCC(ret)) {
func_expr->set_mview_id(mview_id);
func_expr->set_func_name(ObString::make_string(N_SYS_LAST_REFRESH_SCN));
expr = func_expr;
LOG_DEBUG("finish resolve last_refresh_scn expr", K(get_type_name(child_node->type_)), K(func_expr->get_mview_id()));
}
return ret;
}
} //namespace sql
} //namespace oceanbase

View File

@ -210,6 +210,7 @@ private:
int process_xmlparse_node(const ParseNode *node, ObRawExpr *&expr);
void get_special_func_ident_name(ObString &ident_name, const ObItemType func_type);
int process_remote_sequence_node(const ParseNode *node, ObRawExpr *&expr);
int process_last_refresh_scn_node(const ParseNode *expr_node, ObRawExpr *&expr);
int process_dblink_udf_node(const ParseNode *node, ObRawExpr *&expr);
int resolve_dblink_udf_expr(const ParseNode *node,
ObQualifiedName &column_ref,

Some files were not shown because too many files have changed in this diff Show More