diff --git a/deps/oblib/src/common/object/ob_obj_type.cpp b/deps/oblib/src/common/object/ob_obj_type.cpp index 44ebaf98dd..299f6a10d2 100644 --- a/deps/oblib/src/common/object/ob_obj_type.cpp +++ b/deps/oblib/src/common/object/ob_obj_type.cpp @@ -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, diff --git a/deps/oblib/src/common/object/ob_obj_type.h b/deps/oblib/src/common/object/ob_obj_type.h index b76a24c9a5..8f119341f7 100644 --- a/deps/oblib/src/common/object/ob_obj_type.h +++ b/deps/oblib/src/common/object/ob_obj_type.h @@ -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) { diff --git a/src/rootserver/ob_ddl_service.cpp b/src/rootserver/ob_ddl_service.cpp index df27b6edcb..8557ff2e74 100755 --- a/src/rootserver/ob_ddl_service.cpp +++ b/src/rootserver/ob_ddl_service.cpp @@ -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) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("cannot modify column in index table", K(ret)); + } 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), 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,29 +7809,25 @@ 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_))) { - 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()) { - ObArray ref_column_ids; - if (OB_FAIL(column_schema->get_cascaded_column_ids(ref_column_ids))) { - LOG_WARN("fail to get cascade column ids", K(ret)); - } else { - is_in_index = has_exist_in_array(ref_column_ids, column_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()) { + ObArray ref_column_ids; + 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); + } } } } @@ -7883,6 +7903,58 @@ int ObDDLService::check_modify_column_when_upgrade( } return ret; } +int ObDDLService::alter_shadow_column_for_index( + const ObArray &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 &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)); } } diff --git a/src/rootserver/ob_ddl_service.h b/src/rootserver/ob_ddl_service.h index 5f2d00d9a0..61b72888ed 100644 --- a/src/rootserver/ob_ddl_service.h +++ b/src/rootserver/ob_ddl_service.h @@ -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 &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 &idx_schemas, const share::schema::ObColumnSchemaV2 &new_column_schema); diff --git a/src/share/ob_index_builder_util.cpp b/src/share/ob_index_builder_util.cpp index ba7919dc6b..60b9d4cbe5 100644 --- a/src/share/ob_index_builder_util.cpp +++ b/src/share/ob_index_builder_util.cpp @@ -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()) { diff --git a/src/share/ob_index_builder_util.h b/src/share/ob_index_builder_util.h index 27f16ea36e..cc3e05a92f 100644 --- a/src/share/ob_index_builder_util.h +++ b/src/share/ob_index_builder_util.h @@ -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 > OrderFTColumns; diff --git a/src/share/schema/ob_table_schema.cpp b/src/share/schema/ob_table_schema.cpp index 976bb13f30..0d92fbd458 100644 --- a/src/share/schema/ob_table_schema.cpp +++ b/src/share/schema/ob_table_schema.cpp @@ -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", diff --git a/src/storage/memtable/ob_memtable_key.h b/src/storage/memtable/ob_memtable_key.h index c0326c7d94..ac2b228b36 100644 --- a/src/storage/memtable/ob_memtable_key.h +++ b/src/storage/memtable/ob_memtable_key.h @@ -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(),