patch 4.0

This commit is contained in:
wangzelin.wzl
2022-10-24 10:34:53 +08:00
parent 4ad6e00ec3
commit 93a1074b0c
10533 changed files with 2588271 additions and 2299373 deletions

745
src/share/ob_ddl_common.cpp Normal file
View File

@ -0,0 +1,745 @@
/**
* 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 SHARE
#include "ob_ddl_common.h"
#include "common/ob_smart_call.h"
#include "share/ob_autoincrement_service.h"
#include "share/ob_ddl_checksum.h"
#include "share/ob_get_compat_mode.h"
#include "share/ob_rpc_struct.h"
#include "share/schema/ob_multi_version_schema_service.h"
#include "share/schema/ob_schema_getter_guard.h"
#include "share/schema/ob_part_mgr_util.h"
#include "share/location_cache/ob_location_service.h"
#include "sql/engine/ob_physical_plan.h"
#include "sql/engine/table/ob_table_scan_op.h"
using namespace oceanbase::share;
using namespace oceanbase::common;
using namespace oceanbase::share::schema;
using namespace oceanbase::obrpc;
using namespace oceanbase::sql;
int ObColumnNameMap::init(const ObTableSchema &orig_table_schema,
const AlterTableSchema &alter_table_schema)
{
int ret = OB_SUCCESS;
if (OB_FAIL(ObCompatModeGetter::get_table_compat_mode(orig_table_schema.get_tenant_id(), orig_table_schema.get_table_id(), compat_mode_))) {
LOG_WARN("failed to get table compat mode", K(ret));
} else if (OB_FAIL(col_name_map_.create(32, "ColNameMap"))) {
LOG_WARN("failed to create column name map", K(ret));
} else {
lib::CompatModeGuard guard(compat_mode_);
for (ObTableSchema::const_column_iterator it = orig_table_schema.column_begin();
OB_SUCC(ret) && it != orig_table_schema.column_end(); it++) {
ObColumnSchemaV2 *column = *it;
if (OB_ISNULL(column)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid column", K(ret));
} else if (OB_FAIL(set(column->get_column_name_str(), column->get_column_name_str()))) {
LOG_WARN("failed to set colum name map", K(ret));
}
}
for (ObTableSchema::const_column_iterator it = alter_table_schema.column_begin();
OB_SUCC(ret) && it < alter_table_schema.column_end(); it++) {
const AlterColumnSchema *alter_column_schema = nullptr;
if (OB_ISNULL(alter_column_schema = static_cast<AlterColumnSchema *>(*it))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("*it_begin is NULL", K(ret));
} else {
const ObString &orig_column_name = alter_column_schema->get_origin_column_name();
const ObString &new_column_name = alter_column_schema->get_column_name_str();
const ObColumnNameHashWrapper orig_column_key(orig_column_name);
const ObSchemaOperationType op_type = alter_column_schema->alter_type_;
switch (op_type) {
case OB_DDL_DROP_COLUMN: {
// can only drop original table columns
if (OB_FAIL(col_name_map_.erase_refactored(orig_column_key))) {
LOG_WARN("failed to erase from col name map", K(ret));
}
break;
}
case OB_DDL_ADD_COLUMN: {
break;
}
case OB_DDL_CHANGE_COLUMN:
case OB_DDL_MODIFY_COLUMN: {
const ObColumnSchemaV2 *orig_column = nullptr;
if (OB_ISNULL(orig_column = orig_table_schema.get_column_schema(orig_column_name))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("column not in orig table", K(ret));
} else if (orig_column->get_column_name_str() != new_column_name) {
const ObString &column_name = orig_column->get_column_name_str();
if (OB_FAIL(col_name_map_.erase_refactored(ObColumnNameHashWrapper(column_name)))) {
LOG_WARN("failed to erase col name map", K(ret));
} else if (OB_FAIL(set(column_name, new_column_name))) {
LOG_WARN("failed to set col name map", K(ret));
}
}
break;
}
default: {
LOG_DEBUG("ignore unexpected operator", K(ret), KPC(alter_column_schema));
break;
}
}
}
}
}
return ret;
}
int ObColumnNameMap::assign(const ObColumnNameMap &other)
{
int ret = OB_SUCCESS;
if (!other.col_name_map_.created()) {
ret = OB_NOT_INIT;
LOG_WARN("assign from uninitialized name map", K(ret));
} else if (!col_name_map_.created()) {
if (OB_FAIL(col_name_map_.create(32, "ColNameMap"))) {
LOG_WARN("failed to create col name map", K(ret));
}
} else if (OB_FAIL(col_name_map_.reuse())) {
LOG_WARN("failed to clear map", K(ret));
}
if (OB_SUCC(ret)) {
allocator_.reuse();
compat_mode_ = other.compat_mode_;
for (common::hash::ObHashMap<ObColumnNameHashWrapper, ObString>::const_iterator it = other.col_name_map_.begin();
OB_SUCC(ret) && it != other.col_name_map_.end(); it++) {
if (OB_FAIL(set(it->first.column_name_, it->second))) {
LOG_WARN("failed to copy col name map entry", K(ret));
}
}
}
return ret;
}
int ObColumnNameMap::set(const ObString &orig_column_name, const ObString &new_column_name)
{
int ret = OB_SUCCESS;
ObString orig_name;
ObString new_name;
lib::CompatModeGuard guard(compat_mode_);
if (OB_FAIL(deep_copy_ob_string(allocator_, orig_column_name, orig_name))) {
LOG_WARN("failed to copy string", K(ret));
} else if (OB_FAIL(deep_copy_ob_string(allocator_, new_column_name, new_name))) {
LOG_WARN("failed to copy string", K(ret));
} else if (OB_FAIL(col_name_map_.set_refactored(ObColumnNameHashWrapper(orig_name), new_name))) {
LOG_WARN("failed to set col name map", K(ret));
}
return ret;
}
int ObColumnNameMap::get(const ObString &orig_column_name, ObString &new_column_name) const
{
int ret = OB_SUCCESS;
lib::CompatModeGuard guard(compat_mode_);
ret = col_name_map_.get_refactored(ObColumnNameHashWrapper(orig_column_name), new_column_name);
if (OB_HASH_NOT_EXIST == ret) {
ret = OB_ENTRY_NOT_EXIST;
}
return ret;
}
int ObColumnNameMap::get_orig_column_name(const ObString &new_column_name, ObString &orig_column_name) const
{
int ret = OB_SUCCESS;
lib::CompatModeGuard guard(compat_mode_);
if (OB_UNLIKELY(!col_name_map_.created())) {
ret = OB_NOT_INIT;
LOG_WARN("invalid column name map", K(ret));
} else {
const ObColumnNameHashWrapper new_column_key = ObColumnNameHashWrapper(new_column_name);
bool found = false;
for (common::hash::ObHashMap<ObColumnNameHashWrapper, ObString>::const_iterator it = col_name_map_.begin();
OB_SUCC(ret) && !found && it != col_name_map_.end(); it++) {
if (ObColumnNameHashWrapper(it->second) == new_column_key) {
orig_column_name = it->first.column_name_;
found = true;
}
}
if (OB_SUCC(ret) && !found) {
ret = OB_ENTRY_NOT_EXIST;
}
}
return ret;
}
int ObColumnNameMap::get_changed_names(ObIArray<std::pair<ObString, ObString>> &changed_names) const
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(!col_name_map_.created())) {
ret = OB_NOT_INIT;
LOG_WARN("invalid column name map", K(ret));
}
for (common::hash::ObHashMap<ObColumnNameHashWrapper, ObString>::const_iterator it = col_name_map_.begin();
OB_SUCC(ret) && it != col_name_map_.end(); it++) {
if (it->first.column_name_ != it->second) {
if (OB_FAIL(changed_names.push_back(std::make_pair(it->first.column_name_, it->second)))) {
LOG_WARN("failed to push back changed name", K(ret));
}
}
}
return ret;
}
int64_t ObColumnNameMap::to_string(char *buf, const int64_t buf_len) const
{
int ret = OB_SUCCESS;
int64_t pos = 0;
J_OBJ_START();
J_KV(K_(compat_mode));
J_COMMA();
J_NAME("col_name_map");
J_COLON();
J_OBJ_START();
common::hash::ObHashMap<ObColumnNameHashWrapper, ObString>::const_iterator it = col_name_map_.begin();
for (; it != col_name_map_.end(); it++) {
BUF_PRINTO(it->first.column_name_);
J_COLON();
BUF_PRINTO(it->second);
J_COMMA();
}
J_OBJ_END();
J_OBJ_END();
return pos;
}
/****************** ObDDLUtil *************/
int ObDDLUtil::get_tablets(
const uint64_t tenant_id,
const int64_t table_id,
common::ObIArray<common::ObTabletID> &tablet_ids)
{
int ret = OB_SUCCESS;
share::schema::ObSchemaGetterGuard schema_guard;
const share::schema::ObTableSchema *table_schema = nullptr;
if (OB_INVALID_ID == tenant_id || OB_INVALID_ID == table_id) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguments", K(ret), K(tenant_id), K(table_id));
} else if (OB_FAIL(share::schema::ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard(
tenant_id, schema_guard))) {
LOG_WARN("get tenant schema guard failed", K(ret), K(tenant_id));
} else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_id, table_schema))) {
LOG_WARN("get table schema failed", K(ret), K(tenant_id), K(table_id));
} else if (OB_ISNULL(table_schema)) {
ret = OB_TABLE_NOT_EXIST;
LOG_WARN("get table schema failed", K(ret), K(table_id));
} else if (OB_FAIL(table_schema->get_tablet_ids(tablet_ids))) {
LOG_WARN("get tablets failed", K(ret), K(*table_schema));
}
return ret;
}
int ObDDLUtil::refresh_alter_table_arg(
const uint64_t tenant_id,
const int64_t orig_table_id,
obrpc::ObAlterTableArg &alter_table_arg)
{
int ret = OB_SUCCESS;
share::schema::ObSchemaGetterGuard schema_guard;
const share::schema::ObTableSchema *table_schema = nullptr;
const ObDatabaseSchema *db_schema = nullptr;
if (OB_INVALID_ID == tenant_id || OB_INVALID_ID == orig_table_id) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguments", K(ret), K(tenant_id), K(orig_table_id));
} else if (OB_FAIL(share::schema::ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard(
tenant_id, schema_guard))) {
LOG_WARN("get tenant schema guard failed", K(ret), K(tenant_id));
} else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, orig_table_id, table_schema))) {
LOG_WARN("get table schema failed", K(ret), K(tenant_id), K(orig_table_id));
} else if (OB_ISNULL(table_schema)) {
ret = OB_TABLE_NOT_EXIST;
LOG_WARN("table dropped", K(ret), K(tenant_id), K(orig_table_id));
} else if (OB_FAIL(alter_table_arg.alter_table_schema_.set_origin_table_name(table_schema->get_table_name_str()))) {
LOG_WARN("failed to set orig table name", K(ret));
} else if (OB_FAIL(schema_guard.get_database_schema(tenant_id, table_schema->get_database_id(), db_schema))) {
LOG_WARN("fail to get database schema", K(ret), K(tenant_id));
} else if (OB_ISNULL(db_schema)) {
ret = OB_TABLE_NOT_EXIST;
LOG_WARN("database dropped", K(ret), K(tenant_id), K(table_schema->get_database_id()));
} else if (OB_FAIL(alter_table_arg.alter_table_schema_.set_origin_database_name(db_schema->get_database_name_str()))) {
LOG_WARN("failed to set orig database name", K(ret));
}
// refresh constraint
for (ObTableSchema::const_constraint_iterator it = alter_table_arg.alter_table_schema_.constraint_begin();
OB_SUCC(ret) && it != alter_table_arg.alter_table_schema_.constraint_end(); it++) {
ObConstraint *cst = (*it);
const ObConstraint *cur_cst = nullptr;
if (OB_ISNULL(cst)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid cst", K(ret));
} else if (OB_ISNULL(cur_cst = table_schema->get_constraint(cst->get_constraint_id()))) {
LOG_INFO("current constraint not exists, maybe dropped", K(ret), KPC(cst), K(table_schema));
} else if (OB_FAIL(cst->set_constraint_name(cur_cst->get_constraint_name_str()))) {
LOG_WARN("failed to set new constraint name", K(ret));
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(alter_table_arg.based_schema_object_infos_.push_back(ObBasedSchemaObjectInfo(
table_schema->get_table_id(),
TABLE_SCHEMA,
table_schema->get_schema_version())))) {
LOG_WARN("failed to push back base schema object info", K(ret));
} else if (OB_FAIL(alter_table_arg.based_schema_object_infos_.push_back(ObBasedSchemaObjectInfo(
db_schema->get_database_id(),
DATABASE_SCHEMA,
db_schema->get_schema_version())))) {
LOG_WARN("failed to push back base schema object info", K(ret));
}
}
return ret;
}
int ObDDLUtil::generate_column_name_str(
const common::ObIArray<ObColumnNameInfo> &column_names,
const bool is_oracle_mode,
const bool with_origin_name,
const bool with_alias_name,
const bool use_heap_table_ddl_plan,
ObSqlString &sql_string)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(column_names.count() == 0)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguments", K(ret), K(column_names.count()));
} else {
bool with_comma = false;
for (int64_t i = 0; OB_SUCC(ret) && i < column_names.count(); ++i) {
if (use_heap_table_ddl_plan && column_names.at(i).column_name_ == OB_HIDDEN_PK_INCREMENT_COLUMN_NAME) {
} else if (OB_FAIL(generate_column_name_str(column_names.at(i), is_oracle_mode, with_origin_name, with_alias_name, with_comma, sql_string))) {
LOG_WARN("generate column name string failed", K(ret));
} else {
with_comma = true;
}
}
}
return ret;
}
int ObDDLUtil::generate_order_by_str(
const ObIArray<int64_t> &select_column_ids,
const ObIArray<int64_t> &order_column_ids,
ObSqlString &sql_string)
{
int ret = OB_SUCCESS;
if (OB_UNLIKELY(select_column_ids.count() <= 0
|| order_column_ids.count() <= 0)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguments", K(ret), K(select_column_ids), K(order_column_ids));
} else if (OB_FAIL(sql_string.append("order by "))) {
LOG_WARN("append failed", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < order_column_ids.count(); ++i) {
for (int64_t j = 0; OB_SUCC(ret) && j < select_column_ids.count(); ++j) {
const bool append_comma = 0 != i;
if (select_column_ids.at(j) == order_column_ids.at(i)) {
if (OB_FAIL(sql_string.append_fmt("%s %ld", append_comma ? ",": "", j + 1))) {
LOG_WARN("append fmt failed", K(ret));
}
}
}
}
}
return ret;
}
int ObDDLUtil::generate_column_name_str(
const ObColumnNameInfo &column_name_info,
const bool is_oracle_mode,
const bool with_origin_name,
const bool with_alias_name,
const bool with_comma,
ObSqlString &sql_string)
{
int ret = OB_SUCCESS;
const char *split_char = is_oracle_mode ? "\"" : "`";
// append comma
if (with_comma) {
if (OB_FAIL(sql_string.append_fmt(", "))) {
LOG_WARN("append fmt failed", K(ret));
}
}
// append original column name
if (OB_SUCC(ret) && with_origin_name) {
if (OB_FAIL(sql_string.append_fmt("%s%.*s%s", split_char, column_name_info.column_name_.length(), column_name_info.column_name_.ptr(), split_char))) {
LOG_WARN("append origin column name failed", K(ret));
}
}
// append AS
if (OB_SUCC(ret) && with_origin_name && with_alias_name) {
if (OB_FAIL(sql_string.append_fmt(" AS "))) {
LOG_WARN("append as failed", K(ret));
}
}
// append alias column name
if (OB_SUCC(ret) && with_alias_name) {
if (OB_FAIL(sql_string.append_fmt("%s%s%.*s%s", split_char, column_name_info.is_shadow_column_ ? "__SHADOW_" : "",
column_name_info.column_name_.length(), column_name_info.column_name_.ptr(), split_char))) {
LOG_WARN("append alias name failed", K(ret));
}
}
return ret;
}
int ObDDLUtil::generate_ddl_schema_hint_str(
const ObString &table_name,
const int64_t schema_version,
const bool is_oracle_mode,
ObSqlString &sql_string)
{
int ret = OB_SUCCESS;
if (is_oracle_mode) {
if (OB_FAIL(sql_string.append_fmt("ob_ddl_schema_version(\"%.*s\", %ld)",
static_cast<int>(table_name.length()), table_name.ptr(), schema_version))) {
LOG_WARN("append origin column name failed", K(ret));
}
} else {
if (OB_FAIL(sql_string.append_fmt("ob_ddl_schema_version(`%.*s`, %ld)",
static_cast<int>(table_name.length()), table_name.ptr(), schema_version))) {
LOG_WARN("append origin column name failed", K(ret));
}
}
return ret;
}
int ObDDLUtil::generate_build_replica_sql(
const uint64_t tenant_id,
const int64_t data_table_id,
const int64_t dest_table_id,
const int64_t schema_version,
const int64_t snapshot_version,
const int64_t execution_id,
const int64_t task_id,
const int64_t parallelism,
const bool use_heap_table_ddl_plan,
const bool use_schema_version_hint_for_src_table,
const ObColumnNameMap *col_name_map,
ObSqlString &sql_string)
{
int ret = OB_SUCCESS;
ObSchemaGetterGuard schema_guard;
const ObTableSchema *source_table_schema = nullptr;
const ObTableSchema *dest_table_schema = nullptr;
bool oracle_mode = false;
if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || OB_INVALID_ID == data_table_id || OB_INVALID_ID == dest_table_id
|| schema_version <= 0 || snapshot_version <= 0 || execution_id <= 0 || task_id <= 0)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguments", K(ret), K(tenant_id), K(data_table_id), K(dest_table_id), K(schema_version),
K(snapshot_version), K(execution_id), K(task_id));
} else if (OB_FAIL(ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard(
tenant_id, schema_guard, schema_version))) {
LOG_WARN("fail to get tenant schema guard", K(ret), K(data_table_id));
} else if (OB_FAIL(schema_guard.check_formal_guard())) {
LOG_WARN("fail to check formal guard", K(ret));
} else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, data_table_id, source_table_schema))) {
LOG_WARN("fail to get table schema", K(ret), K(tenant_id), K(data_table_id));
} else if (OB_ISNULL(source_table_schema)) {
ret = OB_TABLE_NOT_EXIST;
LOG_WARN("fail to get table schema", K(ret), K(data_table_id));
} else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, dest_table_id, dest_table_schema))) {
LOG_WARN("fail to get table schema", K(ret), K(tenant_id), K(dest_table_id));
} else if (OB_ISNULL(dest_table_schema)) {
ret = OB_TABLE_NOT_EXIST;
LOG_WARN("fail to get table schema", K(ret), K(dest_table_id));
} else if (OB_FAIL(ObCompatModeGetter::check_is_oracle_mode_with_table_id(tenant_id, data_table_id, oracle_mode))) {
LOG_WARN("check if oracle mode failed", K(ret), K(data_table_id));
} else {
ObArray<ObColDesc> column_ids;
ObArray<ObColumnNameInfo> column_names;
ObArray<ObColumnNameInfo> insert_column_names;
ObArray<ObColumnNameInfo> rowkey_column_names;
ObArray<int64_t> select_column_ids;
ObArray<int64_t> order_column_ids;
bool is_shadow_column = false;
int64_t real_parallelism = std::max(1L, parallelism);
real_parallelism = std::min(64L, real_parallelism);
// get dest table column names
if (OB_FAIL(dest_table_schema->get_column_ids(column_ids))) {
LOG_WARN("fail to get column ids", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < column_ids.count(); ++i) {
const ObColumnSchemaV2 *column_schema = nullptr;
ObString orig_column_name;
is_shadow_column = column_ids.at(i).col_id_ >= OB_MIN_SHADOW_COLUMN_ID;
const int64_t col_id = is_shadow_column ? column_ids.at(i).col_id_ - OB_MIN_SHADOW_COLUMN_ID : column_ids.at(i).col_id_;
if (OB_ISNULL(column_schema = dest_table_schema->get_column_schema(col_id))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("error unexpected, column schema must not be nullptr", K(ret));
} else if (is_shadow_column) {
// do nothing
} else if (column_schema->is_generated_column()) {
// cannot insert to generated columns.
} else if (nullptr == col_name_map && OB_FALSE_IT(orig_column_name.assign_ptr(column_schema->get_column_name_str().ptr(), column_schema->get_column_name_str().length()))) {
} else if (nullptr != col_name_map && OB_FAIL(col_name_map->get_orig_column_name(column_schema->get_column_name_str(), orig_column_name))) {
if (OB_ENTRY_NOT_EXIST == ret) {
// newly added column cannot be selected from source table.
ret = OB_SUCCESS;
} else {
LOG_WARN("failed to get orig column name", K(ret));
}
} else if (OB_FAIL(column_names.push_back(ObColumnNameInfo(orig_column_name, is_shadow_column)))) {
LOG_WARN("fail to push back column name", K(ret));
} else if (OB_FAIL(select_column_ids.push_back(col_id))) {
LOG_WARN("push back select column id failed", K(ret), K(col_id));
} else if (!is_shadow_column) {
if (OB_FAIL(insert_column_names.push_back(ObColumnNameInfo(column_schema->get_column_name_str(), is_shadow_column)))) {
LOG_WARN("push back insert column name failed", K(ret));
}
}
}
}
if (OB_SUCC(ret) && source_table_schema->is_heap_table() && dest_table_schema->is_index_local_storage()) {
ObArray<ObColDesc> src_column_ids;
ObSEArray<uint64_t, 5> extra_column_ids;
if (OB_FAIL(source_table_schema->get_column_ids(src_column_ids))) {
LOG_WARN("fail to get column ids", K(ret));
} else {
// Add part keys and their cascaded columns first
for (int64_t i = 0; OB_SUCC(ret) && i < src_column_ids.count(); ++i) {
const ObColumnSchemaV2 *column_schema = nullptr;
const int64_t col_id = src_column_ids.at(i).col_id_;
if (OB_ISNULL(column_schema = source_table_schema->get_column_schema(col_id))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("error unexpected, column schema must not be nullptr", K(ret));
} else if (!column_schema->is_tbl_part_key_column()) {
// do nothing
} else if (OB_FAIL(extra_column_ids.push_back(col_id))) {
LOG_WARN("failed to push column id", K(ret), K(col_id));
} else if (column_schema->is_generated_column()) {
ObSEArray<uint64_t, 5> cascaded_columns;
if (OB_FAIL(column_schema->get_cascaded_column_ids(cascaded_columns))) {
LOG_WARN("failed to get cascaded_column_ids", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < cascaded_columns.count(); ++i) {
uint64_t cascade_col_id = cascaded_columns.at(i);
if (is_contain(extra_column_ids, cascade_col_id)) {
} else if (OB_FAIL(extra_column_ids.push_back(cascade_col_id))) {
LOG_WARN("failed to push cascade column id", K(ret), K(cascade_col_id));
}
}
}
}
}
for (int64_t i = 0; OB_SUCC(ret) && i < extra_column_ids.count(); ++i) {
const ObColumnSchemaV2 *column_schema = nullptr;
ObString orig_column_name;
const int64_t col_id = extra_column_ids.at(i);
if (OB_ISNULL(column_schema = source_table_schema->get_column_schema(col_id))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("error unexpected, column schema must not be nullptr", K(ret));
} else if (is_contain(select_column_ids, col_id)) {
// do nothing
} else if (nullptr == col_name_map && OB_FALSE_IT(orig_column_name.assign_ptr(column_schema->get_column_name_str().ptr(), column_schema->get_column_name_str().length()))) {
} else if (nullptr != col_name_map && OB_FAIL(col_name_map->get_orig_column_name(column_schema->get_column_name_str(), orig_column_name))) {
if (OB_ENTRY_NOT_EXIST == ret) {
// newly added column cannot be selected from source table.
ret = OB_SUCCESS;
} else {
LOG_WARN("failed to get orig column name", K(ret));
}
} else if (OB_FAIL(column_names.push_back(ObColumnNameInfo(orig_column_name, false)))) {
LOG_WARN("fail to push back column name", K(ret));
} else if (OB_FAIL(insert_column_names.push_back(ObColumnNameInfo(column_schema->get_column_name_str(), false)))) {
LOG_WARN("push back insert column name failed", K(ret));
}
}
}
}
// get dest table rowkey columns
if (OB_SUCC(ret)) {
const ObRowkeyInfo &rowkey_info = dest_table_schema->get_rowkey_info();
const ObRowkeyColumn *rowkey_column = nullptr;
const ObColumnSchemaV2 *column_schema = nullptr;
int64_t col_id = 0;
for (int64_t i = 0; OB_SUCC(ret) && i < rowkey_info.get_size(); ++i) {
if (OB_ISNULL(rowkey_column = rowkey_info.get_column(i))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("error unexpected, rowkey column must not be nullptr", K(ret));
} else if (FALSE_IT(is_shadow_column = rowkey_column->column_id_ >= OB_MIN_SHADOW_COLUMN_ID)) {
} else if (FALSE_IT(col_id = is_shadow_column ? rowkey_column->column_id_ - OB_MIN_SHADOW_COLUMN_ID : rowkey_column->column_id_)) {
} else if (OB_ISNULL(column_schema = dest_table_schema->get_column_schema(col_id))) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("error unexpected, column schema must not be nullptr", K(ret), K(col_id));
} else if (column_schema->is_generated_column()) {
// generated columns cannot be row key.
} else if (OB_FAIL(rowkey_column_names.push_back(ObColumnNameInfo(column_schema->get_column_name_str(), is_shadow_column)))) {
LOG_WARN("fail to push back rowkey column name", K(ret));
} else if (OB_FAIL(order_column_ids.push_back(col_id))) {
LOG_WARN("push back order column id failed", K(ret), K(col_id));
}
}
}
// generate build replica sql
if (OB_SUCC(ret)) {
ObSqlString query_column_sql_string;
ObSqlString insert_column_sql_string;
ObSqlString rowkey_column_sql_string;
ObSqlString src_table_schema_version_hint_sql_string;
const ObString &dest_table_name = dest_table_schema->get_table_name_str();
const uint64_t dest_database_id = dest_table_schema->get_database_id();
ObString dest_database_name;
const ObString &source_table_name = source_table_schema->get_table_name_str();
const uint64_t source_database_id = source_table_schema->get_database_id();
ObString source_database_name;
if (OB_SUCC(ret)) {
const ObDatabaseSchema *db_schema = nullptr;
if (OB_FAIL(schema_guard.get_database_schema(tenant_id, dest_database_id, db_schema))) {
LOG_WARN("fail to get database schema", K(ret), K(tenant_id), K(dest_database_id),
K(dest_table_id), K(data_table_id), K(source_database_id));
} else if (OB_ISNULL(db_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("error unexpected, database schema must not be nullptr", K(ret));
} else {
dest_database_name = db_schema->get_database_name_str();
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(schema_guard.get_database_schema(tenant_id, source_database_id, db_schema))) {
LOG_WARN("fail to get database schema", K(ret), K(tenant_id));
} else if (OB_ISNULL(db_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("error unexpected, database schema must not be nullptr", K(ret));
} else {
source_database_name = db_schema->get_database_name_str();
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(generate_column_name_str(column_names, oracle_mode, true/*with origin name*/, true/*with alias name*/, use_heap_table_ddl_plan, query_column_sql_string))) {
LOG_WARN("fail to generate column name str", K(ret));
} else if (OB_FAIL(generate_column_name_str(insert_column_names, oracle_mode, true/*with origin name*/, false/*with alias name*/, use_heap_table_ddl_plan, insert_column_sql_string))) {
LOG_WARN("generate column name str failed", K(ret));
} else if (!use_heap_table_ddl_plan && OB_FAIL(generate_order_by_str(select_column_ids, order_column_ids, rowkey_column_sql_string))) {
LOG_WARN("generate order by string failed", K(ret));
}
}
if (OB_SUCC(ret) && use_schema_version_hint_for_src_table) {
if (OB_FAIL(generate_ddl_schema_hint_str(source_table_name, schema_version, oracle_mode, src_table_schema_version_hint_sql_string))) {
LOG_WARN("failed to generated ddl schema hint", K(ret));
}
}
if (OB_FAIL(ret)) {
} else if (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) use_px */INTO \"%.*s\".\"%.*s\"(%.*s) SELECT /*+ index(\"%.*s\" primary) %.*s */ %.*s from \"%.*s\".\"%.*s\" as of scn %ld %.*s",
real_parallelism, execution_id, task_id,
static_cast<int>(dest_database_name.length()), dest_database_name.ptr(), static_cast<int>(dest_table_name.length()), dest_table_name.ptr(),
static_cast<int>(insert_column_sql_string.length()), insert_column_sql_string.ptr(),
static_cast<int>(source_table_name.length()), source_table_name.ptr(),
static_cast<int>(src_table_schema_version_hint_sql_string.length()), src_table_schema_version_hint_sql_string.ptr(),
static_cast<int>(query_column_sql_string.length()), query_column_sql_string.ptr(),
static_cast<int>(source_database_name.length()), source_database_name.ptr(), static_cast<int>(source_table_name.length()), source_table_name.ptr(),
snapshot_version, static_cast<int>(rowkey_column_sql_string.length()), rowkey_column_sql_string.ptr()))) {
LOG_WARN("fail to assign sql string", K(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) use_px */INTO `%.*s`.`%.*s`(%.*s) SELECT /*+ index(`%.*s` primary) %.*s */ %.*s from `%.*s`.`%.*s` as of snapshot %ld %.*s",
real_parallelism, execution_id, task_id,
static_cast<int>(dest_database_name.length()), dest_database_name.ptr(), static_cast<int>(dest_table_name.length()), dest_table_name.ptr(),
static_cast<int>(insert_column_sql_string.length()), insert_column_sql_string.ptr(),
static_cast<int>(source_table_name.length()), source_table_name.ptr(),
static_cast<int>(src_table_schema_version_hint_sql_string.length()), src_table_schema_version_hint_sql_string.ptr(),
static_cast<int>(query_column_sql_string.length()), query_column_sql_string.ptr(),
static_cast<int>(source_database_name.length()), source_database_name.ptr(), static_cast<int>(source_table_name.length()), source_table_name.ptr(),
snapshot_version, static_cast<int>(rowkey_column_sql_string.length()), rowkey_column_sql_string.ptr()))) {
LOG_WARN("fail to assign sql string", K(ret));
}
}
}
LOG_INFO("execute sql", K(sql_string));
}
return ret;
}
int ObDDLUtil::get_tablet_leader_addr(
share::ObLocationService *location_service,
const uint64_t tenant_id,
const ObTabletID &tablet_id,
const int64_t timeout,
ObLSID &ls_id,
ObAddr &leader_addr)
{
int ret = OB_SUCCESS;
const bool force_renew = true;
bool is_cache_hit = false;
leader_addr.reset();
const int64_t expire_renew_time = force_renew ? INT64_MAX : 0;
ObTimeoutCtx timeout_ctx;
if (nullptr == location_service || OB_INVALID_ID == tenant_id || !tablet_id.is_valid() || timeout <= 0) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguments", K(ret), KP(location_service), K(tenant_id), K(tablet_id), K(timeout));
} else if (OB_FAIL(timeout_ctx.set_trx_timeout_us(timeout))) {
LOG_WARN("set trx timeout failed", K(ret));
} else if (OB_FAIL(timeout_ctx.set_timeout(timeout))) {
LOG_WARN("set timeout failed", K(ret));
} else if (OB_FAIL(location_service->get(tenant_id, tablet_id, expire_renew_time, is_cache_hit, ls_id))) {
LOG_WARN("fail to get log stream id", K(ret), K(tablet_id));
} else if (OB_FAIL(location_service->get_leader(GCONF.cluster_id,
tenant_id,
ls_id,
force_renew,
leader_addr))) {
LOG_WARN("get leader failed", K(ret), K(ls_id));
}
return ret;
}
// Used in offline ddl to delete all checksum record in __all_ddl_checksum
// DELETE FROM __all_ddl_checksum WHERE
int ObDDLUtil::clear_ddl_checksum(ObPhysicalPlan *phy_plan)
{
int ret = OB_SUCCESS;
if (OB_ISNULL(phy_plan)) {
ret = OB_ERR_UNEXPECTED;
} else {
const int64_t execution_id = phy_plan->get_ddl_execution_id();
const ObOpSpec *root_op_spec = phy_plan->get_root_op_spec();
uint64_t table_scan_table_id = OB_INVALID_ID;
if (OB_FAIL(find_table_scan_table_id(root_op_spec, table_scan_table_id))) {
LOG_WARN("failed to get table scan table id", K(ret));
} else if (OB_FAIL(ObDDLChecksumOperator::delete_checksum(MTL_ID(),
execution_id,
table_scan_table_id,
phy_plan->get_ddl_table_id(),
phy_plan->get_ddl_task_id(),
*GCTX.sql_proxy_))) {
LOG_WARN("failed to delete checksum", K(ret));
}
}
return ret;
}
int ObDDLUtil::find_table_scan_table_id(const ObOpSpec *spec, uint64_t &table_id) {
int ret = OB_SUCCESS;
if (OB_ISNULL(spec) || OB_INVALID_ID != table_id) {
/*do nothing*/
} else if (spec->is_table_scan()) {
table_id = static_cast<const ObTableScanSpec *>(spec)->get_ref_table_id();
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < spec->get_child_cnt(); ++i) {
if (OB_FAIL(SMART_CALL(find_table_scan_table_id(spec->get_child(i), table_id)))) {
LOG_WARN("fail to find sample scan", K(ret));
}
}
}
return ret;
}