[FEAT MERGE] 4.3 online ddl column type change
This commit is contained in:
56
deps/oblib/src/common/object/ob_obj_type.cpp
vendored
56
deps/oblib/src/common/object/ob_obj_type.cpp
vendored
@ -642,6 +642,62 @@ int ob_urowid_str(char *buff, int64_t buff_length, int64_t &pos, int64_t length,
|
||||
return databuff_printf(buff, buff_length, pos, "urowid(%ld)", length);
|
||||
}
|
||||
|
||||
bool is_match_alter_integer_column_online_ddl_rules(const common::ObObjMeta& src_meta,
|
||||
const common::ObObjMeta& dst_meta)
|
||||
{
|
||||
bool is_online_ddl = false;
|
||||
if ((((src_meta.is_signed_integer() && dst_meta.is_signed_integer())
|
||||
|| (src_meta.is_unsigned_integer() && dst_meta.is_unsigned_integer())) // both are singed or unsigned integer
|
||||
&& src_meta.get_type() <= dst_meta.get_type())) { // (unsigned) integer can be changed into larger by online ddl
|
||||
is_online_ddl = true;
|
||||
} else if (src_meta.is_unsigned_integer() && dst_meta.is_signed_integer()) {
|
||||
if (src_meta.is_utinyint()) {
|
||||
if (dst_meta.get_type() >= ObSmallIntType && dst_meta.get_type() <= ObIntType) { // unsigned tinyint -> smallint mediumint int bigint
|
||||
is_online_ddl = true;
|
||||
}
|
||||
} else if (src_meta.is_usmallint()) {
|
||||
if (dst_meta.get_type() >= ObMediumIntType && dst_meta.get_type() <= ObIntType) { // unsigned smallint -> mediumint int bigint
|
||||
is_online_ddl = true;
|
||||
}
|
||||
} else if (src_meta.is_umediumint()) {
|
||||
if (dst_meta.get_type() >= ObInt32Type && dst_meta.get_type() <= ObIntType) { // unsigned mediumint -> int bigint
|
||||
is_online_ddl = true;
|
||||
}
|
||||
} else if (src_meta.is_uint32()) {
|
||||
if (dst_meta.is_int()) { // unsigned int -> bigint
|
||||
is_online_ddl = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return is_online_ddl;
|
||||
}
|
||||
|
||||
bool is_match_alter_string_column_online_ddl_rules(const common::ObObjMeta& src_meta,
|
||||
const common::ObObjMeta& dst_meta,
|
||||
const int32_t src_len,
|
||||
const int32_t dst_len)
|
||||
{
|
||||
bool is_online_ddl = false;
|
||||
if (src_len > dst_len
|
||||
|| src_meta.get_charset_type() != dst_meta.get_charset_type()
|
||||
|| src_meta.get_collation_type() != dst_meta.get_collation_type()) {
|
||||
// is_online_ddl = false;
|
||||
} else if ((src_meta.is_varbinary() && dst_meta.is_blob() && ObTinyTextType == dst_meta.get_type()) // varbinary -> tinyblob; depended by generated column
|
||||
|| (src_meta.is_varchar() && dst_meta.is_text() && ObTinyTextType == dst_meta.get_type()) // varchar -> tinytext; depended by generated column
|
||||
|| (dst_meta.is_varbinary() && src_meta.is_blob() && ObTinyTextType == src_meta.get_type()) // tinyblob -> varbinary; depended by generated column
|
||||
|| (dst_meta.is_varchar() && src_meta.is_text() && ObTinyTextType == src_meta.get_type())) { // tinytext -> varchar; depended by generated column
|
||||
// support online ddl with generated column depended:
|
||||
// varbinary -> tinyblob, varchar -> tinytext, tinyblob -> varbinary and tinytext -> varchar in version 4.3
|
||||
is_online_ddl = true;
|
||||
} else if (((src_meta.is_blob() && ObTinyTextType != src_meta.get_type() && dst_meta.is_blob() && ObTinyTextType != dst_meta.get_type()) // tinyblob -x-> blob ---> mediumblob ---> logblob
|
||||
|| (src_meta.is_text() && ObTinyTextType != src_meta.get_type() && dst_meta.is_text() && ObTinyTextType != dst_meta.get_type()))) { // tinytext -x-> text ---> mediumtext ---> longtext
|
||||
// support online ddl with generated column depended:
|
||||
// smaller lob -> larger lob;
|
||||
is_online_ddl = true;
|
||||
}
|
||||
return is_online_ddl;
|
||||
}
|
||||
|
||||
int ob_sql_type_str(char *buff,
|
||||
int64_t buff_length,
|
||||
int64_t &pos,
|
||||
|
||||
7
deps/oblib/src/common/object/ob_obj_type.h
vendored
7
deps/oblib/src/common/object/ob_obj_type.h
vendored
@ -1269,7 +1269,12 @@ inline bool ob_is_unsigned_type(ObObjType type)
|
||||
|| ObUDoubleType == type
|
||||
|| ObUNumberType == type;
|
||||
}
|
||||
|
||||
bool is_match_alter_integer_column_online_ddl_rules(const common::ObObjMeta& src_meta,
|
||||
const common::ObObjMeta& dst_meta);
|
||||
bool is_match_alter_string_column_online_ddl_rules(const common::ObObjMeta& src_meta,
|
||||
const common::ObObjMeta& dst_meta,
|
||||
const int32_t src_len,
|
||||
const int32_t dst_len);
|
||||
inline void convert_unsigned_type_to_signed(ObObjType &type)
|
||||
{
|
||||
switch(type) {
|
||||
|
||||
@ -7714,19 +7714,43 @@ int ObDDLService::rebuild_constraint_check_expr(
|
||||
int ObDDLService::check_can_alter_column_type(
|
||||
const share::schema::ObColumnSchemaV2 &src_column,
|
||||
const share::schema::ObColumnSchemaV2 &dst_column,
|
||||
const share::schema::ObTableSchema &table_schema)
|
||||
const share::schema::ObTableSchema &table_schema,
|
||||
const bool is_oracle_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool is_change_column_type = false;
|
||||
bool is_in_index = false;
|
||||
bool has_generated_depend = src_column.has_generated_column_deps();
|
||||
if (OB_FAIL(check_is_change_column_type(src_column, dst_column, is_change_column_type))) {
|
||||
LOG_WARN("fail to check is change column type", K(ret), K(src_column), K(dst_column));
|
||||
} else if (is_change_column_type) {
|
||||
if (OB_FAIL(check_column_in_index(src_column.get_column_id(), table_schema, is_in_index))) {
|
||||
LOG_WARN("fail to check column is in index table", K(ret));
|
||||
} else if (is_in_index) {
|
||||
} else if (is_in_index || has_generated_depend) {
|
||||
// is_in_index==true means : src_column is 'the index column' or 'index create by user'.
|
||||
const common::ObObjMeta &src_meta = src_column.get_meta_type();
|
||||
const common::ObObjMeta &dst_meta = dst_column.get_meta_type();
|
||||
if (is_oracle_mode) {
|
||||
// in oracle mode
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("cannot modify column in index table", K(ret));
|
||||
LOG_WARN("cannot modify column in index table", K(ret), K(src_column), K(dst_column), K(table_schema));
|
||||
} else {
|
||||
// in mysql mode
|
||||
uint64_t data_version = 0;
|
||||
if (OB_FAIL(GET_MIN_DATA_VERSION(table_schema.get_tenant_id(), data_version))) {
|
||||
LOG_WARN("fail to get data version", KR(ret), K(table_schema.get_tenant_id()));
|
||||
} else if (((has_generated_depend && !is_in_index) || data_version >= DATA_VERSION_4_2_2_0)
|
||||
&& common::is_match_alter_integer_column_online_ddl_rules(src_meta, dst_meta)) {
|
||||
// support online ddl with index, generated column depended:
|
||||
// smaller integer -> big integer in mysql mode in version 4.2.2
|
||||
} else if (((has_generated_depend && !is_in_index) || data_version >= DATA_VERSION_4_3_0_0)
|
||||
&& common::is_match_alter_string_column_online_ddl_rules(src_meta, dst_meta, src_column.get_data_length(), dst_column.get_data_length())) {
|
||||
// generated column type change of: varchar <-> tinytext; varbinary <-> tinyblob; smaller lob -> larger lob; (4.3.0.0)
|
||||
} else {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_WARN("cannot modify column in index table", K(ret), K(src_column), K(dst_column), K(table_schema), K(data_version));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -7785,21 +7809,12 @@ int ObDDLService::check_column_in_index(
|
||||
LOG_WARN("fail to get column ids", K(ret));
|
||||
}
|
||||
for (int64_t j = 0; OB_SUCC(ret) && !is_in_index && j < column_ids.count(); ++j) {
|
||||
const ObColumnSchemaV2 *column_schema = NULL;
|
||||
if (column_id == column_ids.at(j).col_id_) {
|
||||
is_in_index = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && !is_in_index) {
|
||||
column_ids.reuse();
|
||||
if (OB_FAIL(table_schema.get_column_ids(column_ids))) {
|
||||
LOG_WARN("fail to get column ids", K(ret));
|
||||
} else {
|
||||
for (int64_t j = 0; OB_SUCC(ret) && !is_in_index && j < column_ids.count(); ++j) {
|
||||
const ObColumnSchemaV2 *column_schema = NULL;
|
||||
if (OB_ISNULL(column_schema = table_schema.get_column_schema(column_ids.at(j).col_id_))) {
|
||||
} else if (column_ids.at(j).col_id_ > common::OB_MIN_SHADOW_COLUMN_ID) {
|
||||
// table schema get column_schema by shadow_column_id, the result is nullptr;
|
||||
} else if (OB_ISNULL(column_schema = table_schema.get_column_schema(column_ids.at(j).col_id_))) {
|
||||
ret = OB_SCHEMA_ERROR;
|
||||
LOG_WARN("column schema must not be NULL", K(ret), K(column_ids.at(j)));
|
||||
} else if (column_schema->is_generated_column()) {
|
||||
@ -7807,6 +7822,10 @@ int ObDDLService::check_column_in_index(
|
||||
if (OB_FAIL(column_schema->get_cascaded_column_ids(ref_column_ids))) {
|
||||
LOG_WARN("fail to get cascade column ids", K(ret));
|
||||
} else {
|
||||
/*
|
||||
If the column (namely A) is depended by a generated column, and users build an index on the generated column.
|
||||
We consider the column (A) is in index.
|
||||
*/
|
||||
is_in_index = has_exist_in_array(ref_column_ids, column_id);
|
||||
}
|
||||
}
|
||||
@ -7814,6 +7833,7 @@ int ObDDLService::check_column_in_index(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -7883,6 +7903,58 @@ int ObDDLService::check_modify_column_when_upgrade(
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int ObDDLService::alter_shadow_column_for_index(
|
||||
const ObArray<ObTableSchema> &idx_schema_array,
|
||||
const AlterColumnSchema *alter_column_schema,
|
||||
const ObColumnSchemaV2 &new_column_schema,
|
||||
ObDDLOperator &ddl_operator,
|
||||
common::ObMySQLTransaction &trans)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(alter_column_schema)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument", K(ret), KP(alter_column_schema));
|
||||
} else if (!new_column_schema.is_rowkey_column()) {
|
||||
// column is not rowkey column, need not update
|
||||
} else {
|
||||
const ObColumnSchemaV2 *origin_shadow_column_schema = nullptr;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < idx_schema_array.count(); ++i) {
|
||||
const ObTableSchema& idx_table_schema = idx_schema_array.at(i);
|
||||
if (idx_table_schema.get_shadow_rowkey_column_num() > 0) {
|
||||
const ObColumnSchemaV2 *origin_shadow_column_schema = nullptr;
|
||||
if (OB_ISNULL(origin_shadow_column_schema = idx_table_schema.get_column_schema(alter_column_schema->get_column_id() + common::OB_MIN_SHADOW_COLUMN_ID))) {
|
||||
ret = OB_ENTRY_NOT_EXIST;
|
||||
LOG_WARN("origin_shadow_column not exist", K(ret), KPC(alter_column_schema), K(idx_table_schema));
|
||||
} else if (!origin_shadow_column_schema->is_rowkey_column()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("origin_shadow_column_schema is not rowkey column", K(ret), K(idx_table_schema), KPC(origin_shadow_column_schema));
|
||||
} else {
|
||||
SMART_VAR(ObColumnSchemaV2, new_aux_column_schema) {
|
||||
new_aux_column_schema.reset();
|
||||
if (OB_FAIL(new_aux_column_schema.assign(*origin_shadow_column_schema))){
|
||||
LOG_WARN("fail to assgin new_aux_column_schema", K(ret), KPC(origin_shadow_column_schema));
|
||||
} else if (OB_FAIL(fill_new_column_attributes(*alter_column_schema, new_aux_column_schema))) {
|
||||
LOG_WARN("failed to fill new column attributes", K(ret), KPC(alter_column_schema), K(new_aux_column_schema));
|
||||
} else if (OB_FAIL(ObIndexBuilderUtil::set_shadow_column_info(origin_shadow_column_schema->get_column_name(), origin_shadow_column_schema->get_column_id(), new_aux_column_schema))) {
|
||||
LOG_WARN("fail to set shadow_column_info", K(ret), K(new_aux_column_schema), K(origin_shadow_column_schema->get_column_name()));
|
||||
} else if (OB_FAIL(ddl_operator.update_single_column(trans,
|
||||
idx_table_schema,
|
||||
idx_table_schema,
|
||||
new_aux_column_schema))) {
|
||||
LOG_WARN("schema service update aux column failed", K(ret), K(idx_table_schema), K(new_aux_column_schema));
|
||||
} else if (OB_FAIL(ddl_operator.sync_aux_schema_version_for_history(
|
||||
trans,
|
||||
idx_table_schema))) {
|
||||
LOG_WARN("fail to update aux schema version for update column", K(ret), K(idx_table_schema));
|
||||
}
|
||||
} // end SMART_VAR
|
||||
}
|
||||
}
|
||||
} // end for
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int ObDDLService::check_new_column_for_index(
|
||||
ObIArray<ObTableSchema> &idx_schemas,
|
||||
@ -9090,6 +9162,8 @@ int ObDDLService::alter_table_column(const ObTableSchema &origin_table_schema,
|
||||
} else if (OB_FAIL(ddl_operator.update_single_column(
|
||||
trans, origin_table_schema, new_table_schema, new_column_schema))) {
|
||||
RS_LOG(WARN, "failed to alter column", K(alter_column_schema), K(ret));
|
||||
} else if (OB_FAIL(alter_shadow_column_for_index(idx_schema_array, alter_column_schema, new_column_schema, ddl_operator, trans))) {
|
||||
RS_LOG(WARN, "failed to alter shadow column for index", K(ret));
|
||||
} else if (OB_FAIL(alter_table_update_index_and_view_column(
|
||||
new_table_schema,
|
||||
new_column_schema,
|
||||
@ -9182,7 +9256,7 @@ int ObDDLService::alter_table_column(const ObTableSchema &origin_table_schema,
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(check_can_alter_column_type(*orig_column_schema, *alter_column_schema, origin_table_schema))) {
|
||||
if (OB_FAIL(check_can_alter_column_type(*orig_column_schema, *alter_column_schema, origin_table_schema, is_oracle_mode))) {
|
||||
LOG_WARN("fail to check can alter column type", K(ret));
|
||||
}
|
||||
}
|
||||
@ -9220,6 +9294,8 @@ int ObDDLService::alter_table_column(const ObTableSchema &origin_table_schema,
|
||||
new_table_schema,
|
||||
new_column_schema))) {
|
||||
RS_LOG(WARN, "failed to alter column", K(alter_column_schema), K(ret));
|
||||
} else if (OB_FAIL(alter_shadow_column_for_index(idx_schema_array, alter_column_schema, new_column_schema, ddl_operator, trans))) {
|
||||
RS_LOG(WARN, "failed to alter shadow column for index", K(ret));
|
||||
} else if (OB_FAIL(alter_table_update_index_and_view_column(new_table_schema,
|
||||
new_column_schema,
|
||||
ddl_operator,
|
||||
@ -35552,7 +35628,7 @@ int ObDDLService::prepare_change_modify_column_online(AlterColumnSchema &alter_c
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(check_can_alter_column_type(*orig_column_schema, alter_column_schema,
|
||||
origin_table_schema))) {
|
||||
origin_table_schema, is_oracle_mode))) {
|
||||
LOG_WARN("fail to check can alter column type", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1802,7 +1802,8 @@ private:
|
||||
int check_can_alter_column_type(
|
||||
const share::schema::ObColumnSchemaV2 &src_column,
|
||||
const share::schema::ObColumnSchemaV2 &dst_column,
|
||||
const share::schema::ObTableSchema &table_schema);
|
||||
const share::schema::ObTableSchema &table_schema,
|
||||
const bool is_oracle_mode);
|
||||
int check_is_change_column_type(
|
||||
const share::schema::ObColumnSchemaV2 &src_column,
|
||||
const share::schema::ObColumnSchemaV2 &dst_column,
|
||||
@ -1817,6 +1818,13 @@ private:
|
||||
int check_modify_column_when_upgrade(
|
||||
const share::schema::ObColumnSchemaV2 &new_column,
|
||||
const share::schema::ObColumnSchemaV2 &orig_column);
|
||||
int alter_shadow_column_for_index(
|
||||
const ObArray<ObTableSchema> &idx_schema_array,
|
||||
const AlterColumnSchema *alter_column_schema,
|
||||
const ObColumnSchemaV2 &new_column_schema,
|
||||
ObDDLOperator &ddl_operator,
|
||||
common::ObMySQLTransaction &trans);
|
||||
|
||||
int check_new_column_for_index(
|
||||
ObIArray<share::schema::ObTableSchema> &idx_schemas,
|
||||
const share::schema::ObColumnSchemaV2 &new_column_schema);
|
||||
|
||||
@ -138,7 +138,27 @@ int ObIndexBuilderUtil::add_column(
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObIndexBuilderUtil::set_shadow_column_info(
|
||||
const ObString &src_column_name,
|
||||
const uint64_t src_column_id,
|
||||
ObColumnSchemaV2 &shadow_column_schema) {
|
||||
int ret = OB_SUCCESS;
|
||||
shadow_column_schema.set_nullable(true);
|
||||
//the shadow pk is an independent column
|
||||
//so it should not inherit the column flags of the original pk
|
||||
shadow_column_schema.set_column_flags(0);
|
||||
ObObj default_obj;
|
||||
default_obj.set_null();
|
||||
shadow_column_schema.set_cur_default_value(default_obj);
|
||||
shadow_column_schema.set_orig_default_value(default_obj);
|
||||
shadow_column_schema.set_tbl_part_key_pos(0);
|
||||
shadow_column_schema.set_column_id(src_column_id);
|
||||
shadow_column_schema.set_is_hidden(true);
|
||||
if (OB_FAIL(shadow_column_schema.set_column_name(src_column_name))) {
|
||||
LOG_WARN("set_column_name failed", K(src_column_name), K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int ObIndexBuilderUtil::add_shadow_pks(
|
||||
const ObTableSchema &data_schema,
|
||||
ObRowDesc &row_desc,
|
||||
@ -187,19 +207,8 @@ int ObIndexBuilderUtil::add_shadow_pks(
|
||||
K(column_id), K(ret));
|
||||
} else {
|
||||
data_column = *const_data_column;
|
||||
data_column.set_nullable(true);
|
||||
//the shadow pk is an independent column
|
||||
//so it should not inherit the column flags of the original pk
|
||||
data_column.set_column_flags(0);
|
||||
ObObj default_obj;
|
||||
default_obj.set_null();
|
||||
data_column.set_cur_default_value(default_obj);
|
||||
data_column.set_orig_default_value(default_obj);
|
||||
data_column.set_tbl_part_key_pos(0);
|
||||
data_column.set_column_id(OB_MIN_SHADOW_COLUMN_ID + const_data_column->get_column_id());
|
||||
data_column.set_is_hidden(true);
|
||||
if (OB_FAIL(data_column.set_column_name(shadow_pk_name))) {
|
||||
LOG_WARN("set_column_name failed", KCSTRING(shadow_pk_name), K(ret));
|
||||
if (OB_FAIL(set_shadow_column_info(shadow_pk_name, common::OB_MIN_SHADOW_COLUMN_ID + const_data_column->get_column_id(), data_column))) {
|
||||
LOG_WARN("fail to set shadow_column_info", K(ret), K(data_column), K(shadow_pk_name));
|
||||
} else {
|
||||
// primary key(uk2, uk1)
|
||||
if (data_column.get_column_id() > schema.get_max_used_column_id()) {
|
||||
|
||||
@ -73,6 +73,10 @@ public:
|
||||
share::schema::ObTableSchema &table_schema,
|
||||
const bool is_hidden,
|
||||
const bool is_specified_storing_col);
|
||||
static int set_shadow_column_info(
|
||||
const ObString &src_column_name,
|
||||
const uint64_t src_column_id,
|
||||
ObColumnSchemaV2 &shadow_column_schema);
|
||||
private:
|
||||
static const int SPATIAL_MBR_COLUMN_MAX_LENGTH = 32;
|
||||
typedef common::ObArray<std::pair<int64_t, common::ObString> > OrderFTColumns;
|
||||
|
||||
@ -4475,10 +4475,8 @@ int ObTableSchema::check_alter_column_type(const ObColumnSchemaV2 &src_column,
|
||||
} else {
|
||||
// in mysql mode
|
||||
if (!is_type_reduction &&
|
||||
((src_meta.is_integer_type() && dst_meta.is_integer_type())
|
||||
|| (src_meta.is_varbinary() && dst_meta.is_blob())
|
||||
|| (src_meta.is_text() && (dst_meta.is_text() || dst_meta.is_varchar()))
|
||||
|| (src_meta.is_blob() && (dst_meta.is_blob() || dst_meta.is_varbinary())))) {
|
||||
(common::is_match_alter_integer_column_online_ddl_rules(src_meta, dst_meta) // smaller integer -> larger integer
|
||||
|| common::is_match_alter_string_column_online_ddl_rules(src_meta, dst_meta, src_col_byte_len, dst_col_byte_len))) { // varchar, tinytext; varbinary, tinyblob; lob;
|
||||
// online, do nothing
|
||||
} else {
|
||||
is_offline = true;
|
||||
@ -4574,7 +4572,8 @@ int ObTableSchema::check_prohibition_rules(const ObColumnSchemaV2 &src_schema,
|
||||
} else if (OB_FAIL(check_alter_column_in_foreign_key(src_schema, dst_schema, is_oracle_mode))) {
|
||||
LOG_WARN("failed to check alter column in foreign key", K(ret));
|
||||
} else if (!is_oracle_mode
|
||||
&& is_column_in_check_constraint(src_schema.get_column_id())) {
|
||||
&& (is_column_in_check_constraint(src_schema.get_column_id())
|
||||
&& !common::is_match_alter_integer_column_online_ddl_rules(src_schema.get_meta_type(), dst_schema.get_meta_type()))) {
|
||||
// The column contains the check constraint to prohibit modification of the type in mysql mode
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Alter column with check constraint");
|
||||
@ -4616,6 +4615,7 @@ int ObTableSchema::check_ddl_type_change_rules(const ObColumnSchemaV2 &src_colum
|
||||
bool is_rowkey = false;
|
||||
bool is_index = false;
|
||||
bool is_same = false;
|
||||
uint64_t data_version = 0;
|
||||
const ColumnType src_col_type = src_column.get_data_type();
|
||||
const ColumnType dst_col_type = dst_column.get_data_type();
|
||||
const ObObjMeta &src_meta = src_column.get_meta_type();
|
||||
@ -4628,8 +4628,10 @@ int ObTableSchema::check_ddl_type_change_rules(const ObColumnSchemaV2 &src_colum
|
||||
} else if (is_same) {
|
||||
// do nothing
|
||||
} else if (!is_offline) {
|
||||
if (is_oracle_mode) {
|
||||
if (!ob_is_number_tc(src_col_type) &&
|
||||
if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id_, data_version))) {
|
||||
LOG_WARN("failed to get min data version", K(ret), K(tenant_id_), K(data_version));
|
||||
} else if (is_oracle_mode) {
|
||||
if (!(ob_is_number_tc(src_col_type)) &&
|
||||
((!src_meta.is_varying_len_char_type() &&
|
||||
!src_meta.is_timestamp_tz() &&
|
||||
!src_meta.is_timestamp_ltz() &&
|
||||
@ -4651,8 +4653,8 @@ int ObTableSchema::check_ddl_type_change_rules(const ObColumnSchemaV2 &src_colum
|
||||
is_offline = true;
|
||||
}
|
||||
} else {
|
||||
// MYSQL mode
|
||||
if (!ob_is_number_tc(src_col_type) &&
|
||||
!ob_is_decimal_int_tc(src_col_type) &&
|
||||
((!ob_is_text_tc(src_col_type) &&
|
||||
!src_meta.is_bit() &&
|
||||
!src_meta.is_varchar() &&
|
||||
@ -4661,18 +4663,31 @@ int ObTableSchema::check_ddl_type_change_rules(const ObColumnSchemaV2 &src_colum
|
||||
!src_meta.is_datetime()) ||
|
||||
src_col_type != dst_col_type) &&
|
||||
(!src_meta.is_timestamp() &&
|
||||
(!dst_meta.is_datetime() ||
|
||||
!dst_meta.is_datetime()))) {
|
||||
!dst_meta.is_datetime()) &&
|
||||
!((src_meta.is_char() && dst_meta.is_char()) && // char(x) -> char(y) (y>=x) && src_column has no generated column depended on (rowkey or index)
|
||||
!src_column.has_generated_column_deps()) &&
|
||||
!(src_meta.is_integer_type() && dst_meta.is_integer_type() && data_version >= DATA_VERSION_4_2_2_0)) {
|
||||
/*
|
||||
Note of the judge of data_version:
|
||||
Determine data_version to avoid mixed deployment problems during the upgrade process.
|
||||
During the upgrade process, the memtable_key.h of the old version of the observer will not have different types of defense rules (common::is_match_alter_integer_column_online_ddl_rules).
|
||||
And, the type dismatch may cause 4016 problems;
|
||||
1. This issue only needs to consider the primary key, index and part_key columns, so put the check here.
|
||||
2. In the online ddl conversion released in 4.2.2 and 4.3, only the column type conversion of integer will involve this issue.
|
||||
Therefore, we make a special case where the integer column is used as the primary key or index column.
|
||||
*/
|
||||
if (is_rowkey || src_column.is_tbl_part_key_column()) {
|
||||
is_offline = true;
|
||||
}
|
||||
if (is_index && (!src_meta.is_char() || !dst_meta.is_char())) {
|
||||
if (is_index) {
|
||||
is_offline = true;
|
||||
}
|
||||
}
|
||||
if (is_column_in_foreign_key(src_column.get_column_id()) ||
|
||||
src_column.has_generated_column_deps() ||
|
||||
src_column.is_stored_generated_column()) {
|
||||
|
||||
if (!is_offline &&
|
||||
src_meta.is_char() &&
|
||||
dst_meta.is_char() && // char(x) -> char(y) (y>=x) && src_column has no generated column depended on (common column)
|
||||
src_column.has_generated_column_deps()) {
|
||||
is_offline = true;
|
||||
}
|
||||
if (src_column.is_string_type() || src_column.is_enum_or_set()) {
|
||||
@ -4680,8 +4695,6 @@ int ObTableSchema::check_ddl_type_change_rules(const ObColumnSchemaV2 &src_colum
|
||||
src_column.get_charset_type() != dst_column.get_charset_type()) {
|
||||
is_offline = true;
|
||||
}
|
||||
} else if (src_meta.is_unsigned() != dst_meta.is_unsigned()) {
|
||||
is_offline = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4945,6 +4958,7 @@ int ObTableSchema::check_column_can_be_altered_offline(
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int ObTableSchema::check_column_can_be_altered_online(
|
||||
const ObColumnSchemaV2 *src_schema,
|
||||
ObColumnSchemaV2 *dst_schema) const
|
||||
@ -4991,8 +5005,7 @@ int ObTableSchema::check_column_can_be_altered_online(
|
||||
// support number to float in oracle mode
|
||||
} else if ((src_schema->get_data_type() == dst_schema->get_data_type()
|
||||
&& src_schema->get_collation_type() == dst_schema->get_collation_type())
|
||||
|| (ob_is_integer_type(src_schema->get_data_type()) && // can change int to large scale
|
||||
src_schema->get_data_type_class() == dst_schema->get_data_type_class())
|
||||
|| common::is_match_alter_integer_column_online_ddl_rules(src_schema->get_meta_type(), dst_schema->get_meta_type()) // has to check the changing is valid
|
||||
|| (src_schema->is_string_type() && dst_schema->is_string_type()
|
||||
&& src_schema->get_charset_type() == dst_schema->get_charset_type()
|
||||
&& src_schema->get_collation_type() == dst_schema->get_collation_type())) {
|
||||
@ -5034,8 +5047,8 @@ int ObTableSchema::check_column_can_be_altered_online(
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "modify column to binary type");
|
||||
LOG_WARN("can not modify data to binary type", K(ret), KPC(src_schema), KPC(dst_schema));
|
||||
} else if (ob_is_integer_type(src_schema->get_data_type())
|
||||
&& src_schema->get_data_type() > dst_schema->get_data_type()) {
|
||||
} else if (ob_is_integer_type(src_schema->get_data_type()) && ob_is_integer_type(dst_schema->get_data_type())
|
||||
&& !common::is_match_alter_integer_column_online_ddl_rules(src_schema->get_meta_type(), dst_schema->get_meta_type())) {
|
||||
ret = OB_NOT_SUPPORTED;
|
||||
LOG_USER_ERROR(OB_NOT_SUPPORTED, "Change int data type to small scale");
|
||||
LOG_WARN("can't not change int data type to small scale",
|
||||
|
||||
@ -173,7 +173,10 @@ public:
|
||||
const common::ObObjMeta &schema_meta = columns.at(i).col_type_;
|
||||
if (common::ObNullType != value.get_type()
|
||||
&& common::ObExtendType != value.get_type()
|
||||
&& schema_meta.get_type() != value.get_type()) {
|
||||
&& schema_meta.get_type() != value.get_type()
|
||||
&& !(lib::is_mysql_mode()
|
||||
&& (common::is_match_alter_integer_column_online_ddl_rules(schema_meta, value.get_meta())
|
||||
|| common::is_match_alter_integer_column_online_ddl_rules(value.get_meta(), schema_meta)))) { // small integer -> big integer; mysql mode;
|
||||
TRANS_LOG(WARN, "data/schema type does not match",
|
||||
"index", i,
|
||||
"data_type", value.get_type(),
|
||||
|
||||
Reference in New Issue
Block a user