fix hung when convert to character for partition.
This commit is contained in:
parent
3e788f5391
commit
8129d41b24
@ -3374,19 +3374,6 @@ int ObDDLService::check_alter_table_index(const obrpc::ObAlterTableArg &alter_ta
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLService::check_can_convert_to_character(const share::schema::ObColumnSchemaV2 &column_schema, bool &can_convert)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
can_convert = false;
|
||||
if (OB_UNLIKELY(!column_schema.is_valid())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arguments", K(ret), K(column_schema));
|
||||
} else {
|
||||
can_convert = (column_schema.is_string_type() || column_schema.is_enum_or_set()) && CS_TYPE_BINARY != column_schema.get_collation_type();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLService::check_convert_to_character(obrpc::ObAlterTableArg &alter_table_arg,
|
||||
const ObTableSchema &orig_table_schema,
|
||||
ObDDLType &ddl_type)
|
||||
@ -3421,9 +3408,7 @@ int ObDDLService::check_convert_to_character(obrpc::ObAlterTableArg &alter_table
|
||||
if (OB_ISNULL(col)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("col is NULL", K(ret));
|
||||
} else if (OB_FAIL(check_can_convert_to_character(*col, can_convert))) {
|
||||
LOG_WARN("check can convert to character", K(ret));
|
||||
} else if (can_convert) {
|
||||
} else if (ObDDLUtil::check_can_convert_character(col->get_meta_type())) {
|
||||
if (orig_table_schema.is_column_in_foreign_key(col->get_column_id())) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Alter column charset or collation with foreign key");
|
||||
@ -3577,6 +3562,93 @@ int ObDDLService::alter_table_partition_by(
|
||||
return ret;
|
||||
}
|
||||
|
||||
// convert character set for ObBasePartition, inluding high_bound_val and list_row_values.
|
||||
int ObDDLService::convert_to_character_for_partition(
|
||||
const ObCollationType &to_collation,
|
||||
ObTableSchema &new_table_schema)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObPartitionLevel part_level = new_table_schema.get_part_level();
|
||||
const ObPartitionFuncType part_func_type = new_table_schema.get_part_option().get_part_func_type();
|
||||
const ObPartitionFuncType subpart_func_type = new_table_schema.get_sub_part_option().get_sub_part_func_type();
|
||||
if (PARTITION_LEVEL_MAX <= part_level) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid arg", K(ret), K(part_level), K(new_table_schema));
|
||||
} else if (PARTITION_LEVEL_ZERO == part_level) {
|
||||
// non-partitioned, do nothing.
|
||||
} else {
|
||||
const int64_t part_num = new_table_schema.get_partition_num();
|
||||
ObPartition **part_array = new_table_schema.get_part_array();
|
||||
if (OB_ISNULL(part_array)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null first part array", K(ret), K(part_level), K(part_num), K(part_func_type));
|
||||
}
|
||||
// for the first-level part.
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < part_num; i++) {
|
||||
ObPartition *partition = part_array[i];
|
||||
if (OB_ISNULL(partition)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected err", K(ret));
|
||||
} else if (PARTITION_FUNC_TYPE_RANGE_COLUMNS == part_func_type
|
||||
&& OB_FAIL(partition->convert_character_for_range_columns_part(to_collation))) {
|
||||
LOG_WARN("convert charset failed", K(ret), K(to_collation));
|
||||
} else if (PARTITION_FUNC_TYPE_LIST_COLUMNS == part_func_type
|
||||
&& OB_FAIL(partition->convert_character_for_list_columns_part(to_collation))) {
|
||||
LOG_WARN("convert charset failed", K(ret), K(to_collation));
|
||||
} else if (PARTITION_LEVEL_TWO == part_level) {
|
||||
// for the second-level part.
|
||||
const int64_t subpart_num = partition->get_subpartition_num();
|
||||
ObSubPartition **subpart_array = partition->get_subpart_array();
|
||||
if (OB_ISNULL(subpart_array)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("part array is null", K(ret));
|
||||
} else if (subpart_num < 1) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("sub_part_num less than 1", K(ret));
|
||||
} else {
|
||||
for (int64_t j = 0; OB_SUCC(ret) && j < subpart_num; j++) {
|
||||
ObSubPartition *subpart = subpart_array[j];
|
||||
if (OB_ISNULL(subpart)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected err", K(ret));
|
||||
} else if (PARTITION_FUNC_TYPE_RANGE_COLUMNS == subpart_func_type
|
||||
&& OB_FAIL(subpart->convert_character_for_range_columns_part(to_collation))) {
|
||||
LOG_WARN("convert charset failed", K(ret), K(to_collation));
|
||||
} else if (PARTITION_FUNC_TYPE_LIST_COLUMNS == subpart_func_type
|
||||
&& OB_FAIL(subpart->convert_character_for_list_columns_part(to_collation))) {
|
||||
LOG_WARN("convert charset failed", K(ret), K(to_collation));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// for def subpartition array.
|
||||
if (OB_SUCC(ret) && new_table_schema.has_sub_part_template_def()) {
|
||||
ObSubPartition **def_subpart_array = new_table_schema.get_def_subpart_array();
|
||||
const int64_t def_subpart_num = new_table_schema.get_def_sub_part_num();
|
||||
if (OB_ISNULL(def_subpart_array)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected err, def subpart arr is null", K(ret), K(new_table_schema));
|
||||
} else {
|
||||
ObSubPartition *subpart_info = nullptr;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < def_subpart_num; i++) {
|
||||
if (OB_ISNULL(subpart_info = def_subpart_array[i])) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("sub part is nullptr", K(ret));
|
||||
} else if (PARTITION_FUNC_TYPE_RANGE_COLUMNS == subpart_func_type
|
||||
&& OB_FAIL(subpart_info->convert_character_for_range_columns_part(to_collation))) {
|
||||
LOG_WARN("convert charset failed", K(ret), K(to_collation));
|
||||
} else if (PARTITION_FUNC_TYPE_LIST_COLUMNS == subpart_func_type
|
||||
&& OB_FAIL(subpart_info->convert_character_for_list_columns_part(to_collation))) {
|
||||
LOG_WARN("convert charset failed", K(ret), K(to_collation));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLService::convert_to_character(
|
||||
obrpc::ObAlterTableArg &alter_table_arg,
|
||||
const ObTableSchema &orig_table_schema,
|
||||
@ -3599,15 +3671,16 @@ int ObDDLService::convert_to_character(
|
||||
ObTableSchema::const_column_iterator tmp_end = orig_table_schema.column_end();
|
||||
if (OB_FAIL(orig_table_schema.check_if_oracle_compat_mode(is_oracle_mode))) {
|
||||
LOG_WARN("failed to get oracle mode", K(ret));
|
||||
} else if (is_oracle_mode) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected compat mode", K(ret), K(orig_table_schema));
|
||||
} else {
|
||||
for (; OB_SUCC(ret) && tmp_begin != tmp_end; tmp_begin++) {
|
||||
ObColumnSchemaV2 *orig_col = (*tmp_begin);
|
||||
if (OB_ISNULL(orig_col)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("col is NULL", K(ret));
|
||||
} else if (OB_FAIL(check_can_convert_to_character(*orig_col, can_convert))) {
|
||||
LOG_WARN("check can convert to character", K(ret));
|
||||
} else if (can_convert) {
|
||||
} else if (ObDDLUtil::check_can_convert_character(orig_col->get_meta_type())) {
|
||||
ObColumnSchemaV2 *col = new_table_schema.get_column_schema(orig_col->get_column_name());
|
||||
if (OB_ISNULL(col)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -3625,6 +3698,13 @@ int ObDDLService::convert_to_character(
|
||||
}
|
||||
}
|
||||
}
|
||||
// convert character set for partition.
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(convert_to_character_for_partition(collation_type, new_table_schema))) {
|
||||
LOG_WARN("convert collation type for partition failed", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
OZ (create_user_hidden_table(orig_table_schema,
|
||||
new_table_schema,
|
||||
&alter_table_arg.sequence_ddl_arg_,
|
||||
|
@ -1322,6 +1322,8 @@ private:
|
||||
const int64_t frozen_version,
|
||||
ObDDLOperator &ddl_operator,
|
||||
common::ObMySQLTransaction &trans);
|
||||
int convert_to_character_for_partition(const ObCollationType &to_collation,
|
||||
share::schema::ObTableSchema &new_table_schema);
|
||||
int convert_to_character(obrpc::ObAlterTableArg &alter_table_arg,
|
||||
const share::schema::ObTableSchema &orgin_table_schema,
|
||||
share::schema::ObTableSchema &new_table_schema,
|
||||
@ -2147,7 +2149,6 @@ private:
|
||||
const int64_t part_id,
|
||||
const share::schema::ObPartition *&part);
|
||||
int check_table_pk(const share::schema::ObTableSchema &orig_table_schema);
|
||||
int check_can_convert_to_character(const share::schema::ObColumnSchemaV2 &col_schema, bool &can_convert);
|
||||
int clean_global_context(const ObContextSchema &context_schema);
|
||||
|
||||
int get_hard_code_system_table_schema_(
|
||||
|
@ -276,6 +276,12 @@ public:
|
||||
}
|
||||
static bool need_remote_write(const int ret_code);
|
||||
|
||||
static int check_can_convert_character(const ObObjMeta &obj_meta)
|
||||
{
|
||||
return (obj_meta.is_string_type() || obj_meta.is_enum_or_set())
|
||||
&& CS_TYPE_BINARY != obj_meta.get_collation_type();
|
||||
}
|
||||
|
||||
private:
|
||||
static int generate_column_name_str(
|
||||
const common::ObIArray<ObColumnNameInfo> &column_names,
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "lib/string/ob_sql_string.h"
|
||||
#include "lib/number/ob_number_v2.h"
|
||||
#include "common/ob_zone_type.h"
|
||||
#include "share/ob_ddl_common.h"
|
||||
#include "share/schema/ob_table_schema.h"
|
||||
#include "share/ob_primary_zone_util.h"
|
||||
#include "sql/ob_sql_utils.h"
|
||||
@ -5401,6 +5402,72 @@ int ObBasePartition::set_high_bound_val_with_hex_str(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObBasePartition::convert_character_for_range_columns_part(
|
||||
const ObCollationType &to_collation)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObIAllocator *allocator = get_allocator();
|
||||
if (OB_ISNULL(allocator)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null allocator", K(ret));
|
||||
} else if (low_bound_val_.get_obj_cnt() > 0) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("defensive code, unexpected error", K(ret), K(low_bound_val_));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < high_bound_val_.get_obj_cnt(); i++) {
|
||||
ObObj &obj = high_bound_val_.get_obj_ptr()[i];
|
||||
const ObObjMeta &obj_meta = obj.get_meta();
|
||||
if (obj_meta.is_lob()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected err, lob column can not be part key", K(ret), K(obj_meta));
|
||||
} else if (ObDDLUtil::check_can_convert_character(obj_meta)) {
|
||||
ObString dst_string;
|
||||
if (OB_FAIL(ObCharset::charset_convert(*allocator, obj.get_string(), obj.get_collation_type(),
|
||||
to_collation, dst_string))) {
|
||||
LOG_WARN("charset convert failed", K(ret), K(obj), K(to_collation));
|
||||
} else {
|
||||
obj.set_string(obj.get_type(), dst_string);
|
||||
obj.set_collation_type(to_collation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObBasePartition::convert_character_for_list_columns_part(
|
||||
const ObCollationType &to_collation)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObIAllocator *allocator = get_allocator();
|
||||
if (OB_ISNULL(allocator)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected null allocator", K(ret));
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < list_row_values_.count(); i++) {
|
||||
common::ObNewRow &row = list_row_values_.at(i);
|
||||
for (int64_t j = 0; OB_SUCC(ret) && j < row.get_count(); j++) {
|
||||
ObObj &obj = row.get_cell(j);
|
||||
const ObObjMeta &obj_meta = obj.get_meta();
|
||||
if (obj_meta.is_lob()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected err, lob column can not be part key", K(ret), K(obj_meta));
|
||||
} else if (ObDDLUtil::check_can_convert_character(obj_meta)) {
|
||||
ObString dst_string;
|
||||
if (OB_FAIL(ObCharset::charset_convert(*allocator, obj.get_string(), obj.get_collation_type(),
|
||||
to_collation, dst_string))) {
|
||||
LOG_WARN("charset convert failed", K(ret), K(obj), K(to_collation));
|
||||
} else {
|
||||
obj.set_string(obj.get_type(), dst_string);
|
||||
obj.set_collation_type(to_collation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE(ObBasePartition)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
@ -1939,6 +1939,10 @@ public:
|
||||
PartitionType get_partition_type() const { return partition_type_; }
|
||||
virtual bool is_normal_partition() const = 0;
|
||||
virtual bool is_hidden_partition() const { return share::schema::is_hidden_partition(partition_type_); }
|
||||
|
||||
// convert character set.
|
||||
int convert_character_for_range_columns_part(const ObCollationType &to_collation);
|
||||
int convert_character_for_list_columns_part(const ObCollationType &to_collation);
|
||||
VIRTUAL_TO_STRING_KV(K_(tenant_id), K_(table_id), K_(part_id), K_(name), K_(low_bound_val),
|
||||
K_(high_bound_val), K_(list_row_values), K_(part_idx),
|
||||
K_(is_empty_partition_name), K_(tablet_id));
|
||||
|
Loading…
x
Reference in New Issue
Block a user