diff --git a/mysql-test/suite/innodb/r/instant_alter.result b/mysql-test/suite/innodb/r/instant_alter.result index 14b7aeece25..8753977c0b8 100644 --- a/mysql-test/suite/innodb/r/instant_alter.result +++ b/mysql-test/suite/innodb/r/instant_alter.result @@ -741,8 +741,8 @@ CREATE TABLE t1 (f TINYINT, g SMALLINT UNSIGNED) ENGINE=InnoDB ROW_FORMAT=REDUND INSERT INTO t1 VALUES(127,6502),(-128,33101); ALTER TABLE t1 MODIFY f SMALLINT DEFAULT 12345, MODIFY g BIGINT UNSIGNED DEFAULT 1234567; -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 2 +info: Records: 2 Duplicates: 0 Warnings: 0 SELECT * FROM t1; f g 127 6502 @@ -803,8 +803,8 @@ info: Records: 0 Duplicates: 0 Warnings: 0 ALTER TABLE t1 MODIFY f MEDIUMINT NOT NULL DEFAULT 64802, MODIFY c VARCHAR(20) NOT NULL DEFAULT 'gory', ADD d DATETIME; -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 INSERT INTO t1() VALUES(); INSERT INTO t1 (c,f,d) VALUES ('fury', -8388608, now()); SELECT * FROM t1; @@ -818,23 +818,25 @@ SELECT table_id INTO @table_id1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/t1'; INSERT INTO t1 VALUES (-42, -123456); ALTER TABLE t1 CHANGE t s SMALLINT; -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 SELECT table_id INTO @table_id2 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/t1'; affected rows: 1 ALTER TABLE t1 CHANGE m i INT, ALGORITHM=INSTANT; -ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY +ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY ALTER TABLE t1 CHANGE m i INT; -affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +affected rows: 1 +info: Records: 1 Duplicates: 0 Warnings: 0 SELECT table_id INTO @table_id3 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLESTATS WHERE name = 'test/t1'; affected rows: 1 SELECT @table_id1 = @table_id2, @table_id2 = @table_id3; @table_id1 = @table_id2 @table_id2 = @table_id3 -0 1 +0 0 INSERT IGNORE INTO t1 VALUES (0, -123456); +Warnings: +Warning 1062 Duplicate entry '-123456' for key 'm' REPLACE INTO t1 VALUES(-42, 123456); INSERT IGNORE INTO t1 VALUES(32768, 2147483648); Warnings: @@ -842,11 +844,25 @@ Warning 1264 Out of range value for column 's' at row 1 Warning 1264 Out of range value for column 'i' at row 1 SELECT * FROM t1; s i --42 -123456 -0 -123456 -42 123456 32767 2147483647 DROP TABLE t1; +CREATE TABLE t1 (a SERIAL, b INT, c TINYINT UNIQUE) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +INSERT INTO t1 (c) VALUES(1),(2),(3); +ALTER TABLE t1 MODIFY c BIGINT; +affected rows: 3 +info: Records: 3 Duplicates: 0 Warnings: 0 +UPDATE t1 SET b=1 WHERE c=2; +UPDATE t1 SET c=4 WHERE a=3; +UPDATE t1 SET b=2 WHERE c>3; +UPDATE t1 SET c=c+1; +ERROR 23000: Duplicate entry '2' for key 'c' +SELECT * FROM t1; +a b c +1 NULL 1 +2 1 2 +3 2 4 +DROP TABLE t1; CREATE TABLE t1 (id INT PRIMARY KEY, c2 INT UNIQUE, c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), @@ -1640,6 +1656,22 @@ s i -42 123456 32767 2147483647 DROP TABLE t1; +CREATE TABLE t1 (a SERIAL, b INT, c TINYINT UNIQUE) ENGINE=InnoDB ROW_FORMAT=COMPACT; +INSERT INTO t1 (c) VALUES(1),(2),(3); +ALTER TABLE t1 MODIFY c BIGINT; +affected rows: 3 +info: Records: 3 Duplicates: 0 Warnings: 0 +UPDATE t1 SET b=1 WHERE c=2; +UPDATE t1 SET c=4 WHERE a=3; +UPDATE t1 SET b=2 WHERE c>3; +UPDATE t1 SET c=c+1; +ERROR 23000: Duplicate entry '2' for key 'c' +SELECT * FROM t1; +a b c +1 NULL 1 +2 1 2 +3 2 4 +DROP TABLE t1; CREATE TABLE t1 (id INT PRIMARY KEY, c2 INT UNIQUE, c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), @@ -2433,10 +2465,26 @@ s i -42 123456 32767 2147483647 DROP TABLE t1; +CREATE TABLE t1 (a SERIAL, b INT, c TINYINT UNIQUE) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +INSERT INTO t1 (c) VALUES(1),(2),(3); +ALTER TABLE t1 MODIFY c BIGINT; +affected rows: 3 +info: Records: 3 Duplicates: 0 Warnings: 0 +UPDATE t1 SET b=1 WHERE c=2; +UPDATE t1 SET c=4 WHERE a=3; +UPDATE t1 SET b=2 WHERE c>3; +UPDATE t1 SET c=c+1; +ERROR 23000: Duplicate entry '2' for key 'c' +SELECT * FROM t1; +a b c +1 NULL 1 +2 1 2 +3 2 4 +DROP TABLE t1; disconnect analyze; SELECT variable_value-@old_instant instants FROM information_schema.global_status WHERE variable_name = 'innodb_instant_alter_column'; instants -175 +174 SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; diff --git a/mysql-test/suite/innodb/r/instant_alter_charset,redundant.rdiff b/mysql-test/suite/innodb/r/instant_alter_charset,redundant.rdiff index 9a8dcd45e36..82a5ca95986 100644 --- a/mysql-test/suite/innodb/r/instant_alter_charset,redundant.rdiff +++ b/mysql-test/suite/innodb/r/instant_alter_charset,redundant.rdiff @@ -1,23 +1,5 @@ --- instant_alter_charset.result +++ instant_alter_charset,redundant.result -@@ -143,7 +143,7 @@ - drop index ab, - add unique key ab(a,c), - algorithm=instant; --ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY -+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY - drop table key_part_change; - create table key_part_change_and_rename ( - a char(100) charset ascii, -@@ -156,7 +156,7 @@ - drop index ab, - add unique key ab(a,b), - algorithm=instant; --ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY -+ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: ADD INDEX. Try ALGORITHM=NOCOPY - drop table key_part_change_and_rename; - create table enum_and_set ( - a enum('one', 'two') charset utf8mb3, @@ -254,7 +254,6 @@ alter table boundary_255 modify b varchar(200) charset utf8mb3, diff --git a/mysql-test/suite/innodb/r/instant_alter_extend.result b/mysql-test/suite/innodb/r/instant_alter_extend.result index d353e5f97f4..ca8e566f19c 100644 Binary files a/mysql-test/suite/innodb/r/instant_alter_extend.result and b/mysql-test/suite/innodb/r/instant_alter_extend.result differ diff --git a/mysql-test/suite/innodb/t/instant_alter.test b/mysql-test/suite/innodb/t/instant_alter.test index c36b5801b1e..99f49300b2e 100644 --- a/mysql-test/suite/innodb/t/instant_alter.test +++ b/mysql-test/suite/innodb/t/instant_alter.test @@ -715,6 +715,19 @@ INSERT IGNORE INTO t1 VALUES(32768, 2147483648); SELECT * FROM t1; DROP TABLE t1; +eval CREATE TABLE t1 (a SERIAL, b INT, c TINYINT UNIQUE) $engine; +INSERT INTO t1 (c) VALUES(1),(2),(3); +--enable_info +ALTER TABLE t1 MODIFY c BIGINT; +--disable_info +UPDATE t1 SET b=1 WHERE c=2; +UPDATE t1 SET c=4 WHERE a=3; +UPDATE t1 SET b=2 WHERE c>3; +--error ER_DUP_ENTRY +UPDATE t1 SET c=c+1; +SELECT * FROM t1; +DROP TABLE t1; + dec $format; } disconnect analyze; diff --git a/mysql-test/suite/innodb/t/instant_alter_extend.test b/mysql-test/suite/innodb/t/instant_alter_extend.test index 80f82820afe..6b528c1d30c 100644 --- a/mysql-test/suite/innodb/t/instant_alter_extend.test +++ b/mysql-test/suite/innodb/t/instant_alter_extend.test @@ -1,8 +1,10 @@ --source include/have_innodb.inc +--source include/innodb_row_format.inc --source include/maybe_debug.inc -- echo # -- echo # MDEV-15563: Instant ROW_FORMAT=REDUNDANT column type change&extension +-- echo # (reverted in MDEV-18627) -- echo # # Use character-set-server in test db @@ -10,8 +12,6 @@ create or replace database test; use test; set default_storage_engine=innodb; -set @save_format= @@GLOBAL.innodb_default_row_format; -SET GLOBAL innodb_default_row_format=redundant; set @bigval= repeat('0123456789', 30); delimiter ~~; @@ -45,7 +45,9 @@ set @save_debug= @@SESSION.debug_dbug; set debug_dbug= '+d,ib_instant_error'; --enable_query_log } -alter table t modify a char(200), algorithm=instant; +--enable_info +alter table t modify a char(200); +--disable_info select count(a) from t where a = @bigval; select a, length(a) from t where a = 'z'; @@ -53,7 +55,9 @@ check table t extended; call check_table('t'); --echo # CHAR enlargement -alter table t modify a char(220), algorithm=instant; +--enable_info +alter table t modify a char(220); +--disable_info select count(a) from t where a = @bigval; select a, length(a) from t where a = 'z'; @@ -61,10 +65,10 @@ check table t extended; call check_table('t'); --echo # Convert from VARCHAR to a bigger CHAR ---error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON -alter table t modify a varchar(200), algorithm=instant; -alter table t modify a varchar(200), algorithm=copy; -alter table t modify a char(255), algorithm=instant; +--enable_info +alter table t modify a varchar(200); +alter table t modify a char(255); +--disable_info select count(a) from t where a = @bigval; select a, length(a) from t where a = 'z'; @@ -74,14 +78,17 @@ call check_table('t'); --echo # BINARY/VARBINARY test create or replace table t (a varbinary(300)); ---error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON -alter table t modify a binary(255), algorithm=instant; -alter table t modify a binary(255), algorithm=copy; +insert into t values(NULL); +--enable_info +alter table t modify a binary(255); +--disable_info create or replace table t (a varbinary(200)); insert into t values (@bigval); insert into t values ('z'); -alter table t modify a binary(200), algorithm=instant; +--enable_info +alter table t modify a binary(200); +--disable_info select count(a) from t where a = @bigval; select length(a) from t where left(a, 1) = 'z'; @@ -89,16 +96,18 @@ check table t extended; call check_table('t'); --echo # BINARY enlargement -alter table t modify a binary(220), algorithm=instant; +--enable_info +alter table t modify a binary(220); +--disable_info check table t extended; call check_table('t'); --echo # Convert from VARBINARY to a bigger BINARY ---error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON -alter table t modify a varbinary(220), algorithm=instant; -alter table t modify a varbinary(220), algorithm=copy; -alter table t modify a binary(255), algorithm=instant; +--enable_info +alter table t modify a varbinary(220); +alter table t modify a binary(255); +--disable_info select count(a) from t where a = @bigval; select a, length(a) from t where a = 'z'; @@ -110,25 +119,33 @@ call check_table('t'); --echo # Integer conversions create or replace table t (x tinyint); insert into t values (127); -alter table t modify x smallint, algorithm=instant; +--enable_info +alter table t modify x smallint; +--disable_info select * from t; check table t extended; call check_table('t'); update t set x= 32767; -alter table t modify x mediumint, algorithm=instant; +--enable_info +alter table t modify x mediumint; +--disable_info select * from t; check table t extended; call check_table('t'); update t set x= 8388607; -alter table t modify x int, algorithm=instant; +--enable_info +alter table t modify x int; +--disable_info select * from t; check table t extended; call check_table('t'); update t set x= 2147483647; -alter table t modify x bigint, algorithm=instant; +--enable_info +alter table t modify x bigint; +--disable_info select * from t; check table t extended; call check_table('t'); @@ -163,13 +180,19 @@ call check_table('t2'); create or replace table t1 (x mediumint); insert into t1 values (1); insert into t1 values (1); -alter table t1 add column y int first, modify x int, algorithm instant; +--enable_info +alter table t1 add column y int first, modify x int; --error ER_DUP_ENTRY alter table t1 add column z int first, add primary key (x); +--disable_info --echo # Check assertion in wrong instant operation create or replace table t1 (a varchar(26) not null) default character set utf8mb4; -alter table t1 modify a varchar(25) not null; +insert into t1 values ('abcdef'), (repeat('x',26)); +--enable_info +alter ignore table t1 modify a varchar(25) not null; +--disable_info +select * from t1; --echo # Check row_mysql_store_col_in_innobase_format() create or replace table t1(x int primary key, a varchar(20)); @@ -181,30 +204,46 @@ update t1 set a= 'foo' where x = 2; --echo # create or replace table t1 (x int, y int); insert into t1 (x, y) values (11, 22); -alter table t1 modify x bigint, algorithm instant; -alter table t1 add primary key (x), algorithm inplace; +--enable_info +alter table t1 modify x bigint; +alter table t1 add primary key (x); +--disable_info +select * from t1; check table t1; create or replace table t1 (a varchar(10), y int); insert into t1 (a, y) values ("0123456789", 33); -alter table t1 modify a char(15), algorithm instant; -alter table t1 add primary key (a), algorithm inplace; +--enable_info +alter table t1 modify a char(15); +alter table t1 add primary key (a); +--disable_info +select * from t1; check table t1; create or replace table t1 (x int primary key, y int); insert into t1 (x, y) values (44, 55); -alter table t1 modify x bigint, algorithm inplace; +--enable_info +alter table t1 modify x bigint; +--disable_info +select * from t1; check table t1; create or replace table t1 (x int primary key, y int); insert into t1 values (66, 77); -alter table t1 add column z int, algorithm instant; -alter table t1 drop column y, algorithm instant; +--enable_info +alter table t1 add column z int; +alter table t1 drop column y; +--disable_info +select * from t1; +check table t1; create or replace table t1 (x integer, a varchar(20)); -alter table t1 add index idx3 (a); +--enable_info insert into t1 (x, a) values (73, 'a'); +alter table t1 add index idx3 (a); alter table t1 modify a char(20); +--disable_info +select * from t1; +check table t1; create or replace database test charset latin1; -SET GLOBAL innodb_default_row_format=@save_format; diff --git a/sql/field.cc b/sql/field.cc index 6cef622bf1e..bb4a0f06fc4 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7084,9 +7084,6 @@ uint Field_str::is_equal(Create_field *new_field) return new_field->charset == field_charset ? IS_EQUAL_YES : IS_EQUAL_PACK_LENGTH; - if (table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION) - return IS_EQUAL_PACK_LENGTH_EXT; - return IS_EQUAL_NO; } @@ -7947,11 +7944,6 @@ uint Field_varstring::is_equal(Create_field *new_field) (table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION)) return IS_EQUAL_PACK_LENGTH; // VARCHAR, longer length } - else if (new_type_handler == &type_handler_string) // converting to CHAR - { - if (table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION) - return IS_EQUAL_PACK_LENGTH_EXT; - } return IS_EQUAL_NO; } @@ -9568,22 +9560,6 @@ uint Field_num::is_equal(Create_field *new_field) format for integers, we can only return IS_EQUAL_YES for the TINYINT conversion. */ - if (table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION) - { - /* For now, prohibit instant conversion between BIT and integers. - Note: pack_length(), which is compared below, is measured in - bytes, and for BIT the last byte may be partially occupied. We - must not allow instant conversion to BIT such that the last byte - is partially occupied. - We could allow converting TINYINT UNSIGNED to BIT(8) or wider. */ - if (th != new_th && - (th == &type_handler_bit || new_th == &type_handler_bit)) - return IS_EQUAL_NO; - if (th->result_type() == new_th->result_type() && - new_field->pack_length >= pack_length()) - return IS_EQUAL_PACK_LENGTH_EXT; - } - return IS_EQUAL_NO; } diff --git a/sql/handler.h b/sql/handler.h index afe45f2b8d6..09c9c9a6849 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -751,14 +751,6 @@ typedef ulonglong alter_table_operations; */ #define ALTER_COLUMN_INDEX_LENGTH (1ULL << 60) -/** - Change the column length or type such that no rebuild is needed. - Only set if ALTER_COLUMN_EQUAL_PACK_LENGTH does not apply, and - if HA_EXTENDED_TYPES_CONVERSION holds. - @see IS_EQUAL_PACK_LENGTH_EXT -*/ -#define ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT (1ULL << 61) - /* Flags set in partition_flags when altering partitions */ diff --git a/sql/sql_priv.h b/sql/sql_priv.h index 00d1616df1e..dab7a3161be 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -358,11 +358,6 @@ data dictionary without changing table rows */ #define IS_EQUAL_PACK_LENGTH 2 -/** - new_field has a representation that is compatible with the old type - when the storage engine advertises HA_EXTENDED_TYPES_CONVERSION -*/ -#define IS_EQUAL_PACK_LENGTH_EXT 3 enum enum_parsing_place { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a40febf58f4..4dd9d43a7b9 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6605,9 +6605,6 @@ static bool fill_alter_inplace_info(THD *thd, */ ha_alter_info->handler_flags|= ALTER_COLUMN_EQUAL_PACK_LENGTH; break; - case IS_EQUAL_PACK_LENGTH_EXT: - ha_alter_info->handler_flags|= ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT; - break; default: DBUG_ASSERT(0); /* Safety. */ diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 2db08b1a537..29696f96aa0 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -4839,9 +4839,7 @@ n_field_mismatch: if (len_is_stored(len) && (field->prefix_len ? len > field->prefix_len - : (fixed_size && (page_is_comp(page) - ? len != fixed_size - : len > fixed_size)))) { + : (fixed_size && len != fixed_size))) { len_mismatch: btr_index_rec_validate_report(page, rec, index); ib::error error; diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index ed9fd219d91..59704201c4e 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -486,14 +486,8 @@ incompatible: For the metadata record, variable-length columns are always written with zero length. The DB_TRX_ID will start right after any fixed-length columns. */ - if (index->table->not_redundant()) { - for (uint i = index->n_uniq; i--; ) { - trx_id_offset += index->fields[i] - .fixed_len; - } - } else { - trx_id_offset = rec_get_field_start_offs( - rec, index->n_uniq); + for (uint i = index->n_uniq; i--; ) { + trx_id_offset += index->fields[i].fixed_len; } } diff --git a/storage/innobase/data/data0type.cc b/storage/innobase/data/data0type.cc index 53d019a4664..a154dc6b490 100644 --- a/storage/innobase/data/data0type.cc +++ b/storage/innobase/data/data0type.cc @@ -100,22 +100,6 @@ dtype_validate( return(TRUE); } -bool dict_col_t::same_charset(const dict_col_t& other) const -{ - if (dtype_is_non_binary_string_type(mtype, prtype) - && dtype_is_non_binary_string_type(other.mtype, other.prtype)) { - uint csn1 = (uint) dtype_get_charset_coll(prtype); - uint csn2 = (uint) dtype_get_charset_coll(other.prtype); - CHARSET_INFO* cs1 = get_charset(csn1, MYF(MY_WME)); - CHARSET_INFO* cs2 = get_charset(csn2, MYF(MY_WME)); - if (!my_charset_same(cs1, cs2)) { - return false; - } - } - - return true; -} - #ifdef UNIV_DEBUG /** Print a data type structure. @param[in] type data type */ diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 232a21b99d2..7664bc2064d 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -2203,14 +2203,6 @@ dict_index_too_big_for_tree( } field_max_size = dict_col_get_max_size(col); - if (!comp && (col->mtype == DATA_INT - || col->mtype == DATA_CHAR - || col->mtype == DATA_FIXBINARY)) { - /* DATA_INT, DATA_FIXBINARY and DATA_CHAR are variable- - length (enlarged instantly), but are stored locally. */ - field_ext_max_size = 0; - goto add_field_size; - } field_ext_max_size = field_max_size < 256 ? 1 : 2; if (field->prefix_len) { diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 3eee1730972..b0e58872ad8 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -9977,7 +9977,7 @@ innobase_fts_create_doc_id_key( /* The unique Doc ID field should be an eight-bytes integer */ dict_field_t* field = dict_index_get_nth_field(index, 0); ut_a(field->col->mtype == DATA_INT); - ut_ad(sizeof(*doc_id) == field->col->len); + ut_ad(sizeof(*doc_id) == field->fixed_len); ut_ad(!strcmp(index->name, FTS_DOC_ID_INDEX_NAME)); #endif /* UNIV_DEBUG */ diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 8612aa9404b..3606088d037 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -135,7 +135,6 @@ static const alter_table_operations INNOBASE_ALTER_INSTANT | ALTER_ADD_VIRTUAL_COLUMN | INNOBASE_FOREIGN_OPERATIONS | ALTER_COLUMN_EQUAL_PACK_LENGTH - | ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT | ALTER_COLUMN_UNVERSIONED | ALTER_DROP_VIRTUAL_COLUMN; @@ -270,7 +269,7 @@ inline void dict_table_t::prepare_instant(const dict_table_t& old, ut_ad(!not_redundant()); for (unsigned i = index.n_fields; i--; ) { ut_ad(index.fields[i].col->same_format( - *oindex.fields[i].col, true)); + *oindex.fields[i].col)); } } #endif @@ -458,13 +457,9 @@ inline void dict_index_t::instant_add_field(const dict_index_t& instant) as this index. Fields for any added columns are appended at the end. */ #ifndef DBUG_OFF for (unsigned i = 0; i < n_fields; i++) { - DBUG_ASSERT(fields[i].prefix_len - == instant.fields[i].prefix_len); - DBUG_ASSERT(fields[i].fixed_len - == instant.fields[i].fixed_len - || !table->not_redundant()); - DBUG_ASSERT(instant.fields[i].col->same_format( - *fields[i].col, !table->not_redundant())); + DBUG_ASSERT(fields[i].same(instant.fields[i])); + DBUG_ASSERT(instant.fields[i].col->same_format(*fields[i] + .col)); /* Instant conversion from NULL to NOT NULL is not allowed. */ DBUG_ASSERT(!fields[i].col->is_nullable() || instant.fields[i].col->is_nullable()); @@ -540,7 +535,10 @@ inline bool dict_table_t::instant_column(const dict_table_t& table, if (const dict_col_t* o = find(old_cols, col_map, n_cols, i)) { c.def_val = o->def_val; - ut_ad(c.same_format(*o, !not_redundant())); + DBUG_ASSERT(!((c.prtype ^ o->prtype) + & ~(DATA_NOT_NULL | DATA_VERSIONED))); + DBUG_ASSERT(c.mtype == o->mtype); + DBUG_ASSERT(c.len >= o->len); if (o->vers_sys_start()) { ut_ad(o->ind == vers_start); @@ -1752,10 +1750,6 @@ ha_innobase::check_if_supported_inplace_alter( { DBUG_ENTER("check_if_supported_inplace_alter"); - DBUG_ASSERT(!(ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT - & ha_alter_info->handler_flags) - || !m_prebuilt->table->not_redundant()); - if ((ha_alter_info->handler_flags & INNOBASE_ALTER_VERSIONED_REBUILD) && altered_table->versioned(VERS_TIMESTAMP)) { @@ -2951,7 +2945,7 @@ innobase_col_to_mysql( switch (col->mtype) { case DATA_INT: - ut_ad(len <= flen); + ut_ad(len == flen); /* Convert integer data from Innobase to little-endian format, sign bit restored to normal */ @@ -5592,8 +5586,7 @@ static bool innobase_instant_try( bool update = old && (!ctx->first_alter_pos || i < ctx->first_alter_pos - 1); - ut_ad(!old || col->same_format( - *old, !user_table->not_redundant())); + DBUG_ASSERT(!old || col->same_format(*old)); if (update && old->prtype == d->type.prtype) { /* The record is already present in SYS_COLUMNS. */ @@ -5682,8 +5675,6 @@ add_all_virtual: NULL, trx, ctx->heap, NULL); dberr_t err = DB_SUCCESS; - DBUG_EXECUTE_IF("ib_instant_error", - err = DB_OUT_OF_FILE_SPACE; goto func_exit;); if (rec_is_metadata(rec, *index)) { ut_ad(page_rec_is_user_rec(rec)); if (!page_has_next(block->frame) @@ -9061,7 +9052,7 @@ innobase_rename_or_enlarge_column_try( and ROW_FORMAT is not REDUNDANT and mbminlennot_redundant() || col->len == len); + ut_ad(col->len == len); break; case DATA_BINARY: case DATA_VARCHAR: @@ -9069,11 +9060,6 @@ innobase_rename_or_enlarge_column_try( case DATA_DECIMAL: case DATA_BLOB: break; - case DATA_INT: - if (!user_table->not_redundant()) { - break; - } - /* fall through */ default: ut_ad(col->prtype == prtype); ut_ad(col->mtype == mtype); @@ -9129,7 +9115,6 @@ innobase_rename_or_enlarge_columns_try( if (!(ha_alter_info->handler_flags & (ALTER_COLUMN_EQUAL_PACK_LENGTH - | ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT | ALTER_COLUMN_NAME))) { DBUG_RETURN(false); } @@ -9178,7 +9163,6 @@ innobase_rename_or_enlarge_columns_cache( { if (!(ha_alter_info->handler_flags & (ALTER_COLUMN_EQUAL_PACK_LENGTH - | ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT | ALTER_COLUMN_NAME))) { return; } diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic index 39f00364ea2..9e88ee53559 100644 --- a/storage/innobase/include/data0type.ic +++ b/storage/innobase/include/data0type.ic @@ -472,18 +472,12 @@ dtype_get_fixed_size_low( } #endif /* UNIV_DEBUG */ /* fall through */ + case DATA_CHAR: + case DATA_FIXBINARY: + case DATA_INT: case DATA_FLOAT: case DATA_DOUBLE: return(len); - case DATA_FIXBINARY: - case DATA_CHAR: - case DATA_INT: - /* Treat these types as variable length for redundant - row format. We can't rely on fixed_len anymore because record - can have shorter length from before instant enlargement - [MDEV-15563]. Note, that importing such tablespace to - earlier MariaDB versions produces ER_TABLE_SCHEMA_MISMATCH. */ - return comp ? len : 0; case DATA_MYSQL: if (prtype & DATA_BINARY_TYPE) { return(len); @@ -631,14 +625,6 @@ dtype_get_sql_null_size( const dtype_t* type, /*!< in: type */ ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ { - switch (type->mtype) { - case DATA_INT: - case DATA_CHAR: - case DATA_FIXBINARY: - return(type->len); - default: - break; - } return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len, type->mbminlen, type->mbmaxlen, comp)); } diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index e9ffa660354..11e150c4f78 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -682,52 +682,18 @@ public: def_val.data = NULL; } -private: - /** Determine if the columns have the same character set - @param[in] other column to compare to - @return whether the columns have the same character set */ - bool same_charset(const dict_col_t& other) const; -public: /** Determine if the columns have the same format except for is_nullable() and is_versioned(). @param[in] other column to compare to - @param[in] redundant table is redundant row format @return whether the columns have the same format */ - bool same_format(const dict_col_t& other, bool redundant = false) const + bool same_format(const dict_col_t& other) const { - if (len < other.len - || mbminlen != other.mbminlen - || mbmaxlen != other.mbmaxlen) { - return false; - } - - if (!((prtype ^ other.prtype) - & ~(DATA_NOT_NULL | DATA_VERSIONED))) { - return mtype == other.mtype; - } - - if (redundant) { - switch (other.mtype) { - case DATA_CHAR: - case DATA_MYSQL: - case DATA_VARCHAR: - case DATA_VARMYSQL: - return (mtype == DATA_CHAR - || mtype == DATA_MYSQL - || mtype == DATA_VARCHAR - || mtype == DATA_VARMYSQL) - && same_charset(other); - case DATA_FIXBINARY: - case DATA_BINARY: - return (mtype == DATA_FIXBINARY - || mtype == DATA_BINARY) - && same_charset(other); - case DATA_INT: - return mtype == DATA_INT; - } - } - - return false; + return mtype == other.mtype + && len >= other.len + && mbminlen == other.mbminlen + && mbmaxlen == other.mbmaxlen + && !((prtype ^ other.prtype) + & ~(DATA_NOT_NULL | DATA_VERSIONED)); } }; diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 6de4dda93b1..0913f2d7574 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2018, MariaDB Corporation. +Copyright (c) 2014, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -706,6 +706,11 @@ row_merge_buf_add( row_field, field, col->len, old_table->space->zip_size(), conv_heap); + } else { + /* Field length mismatch should not + happen when rebuilding redundant row + format table. */ + ut_ad(index->table->not_redundant()); } } } diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 1e82c6b6551..071ef9ffd92 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -887,15 +887,10 @@ row_create_prebuilt( == MAX_REF_PARTS);); uint temp_len = 0; for (uint i = 0; i < temp_index->n_uniq; i++) { - const dict_field_t& f = temp_index->fields[i]; - if (f.col->mtype == DATA_INT) { - ut_ad(f.col->len >= f.fixed_len); - /* dtype_get_fixed_size_low() returns 0 - for ROW_FORMAT=REDUNDANT */ - ut_ad(table->not_redundant() - ? f.col->len == f.fixed_len - : f.fixed_len == 0); - temp_len += f.col->len; + ulint type = temp_index->fields[i].col->mtype; + if (type == DATA_INT) { + temp_len += + temp_index->fields[i].fixed_len; } } srch_key_len = std::max(srch_key_len,temp_len); diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index e0b7cdb7145..73ed5f06825 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -2723,8 +2723,6 @@ row_sel_field_store_in_mysql_format_func( switch (templ->type) { const byte* field_end; - case DATA_CHAR: - case DATA_FIXBINARY: case DATA_VARCHAR: case DATA_VARMYSQL: case DATA_BINARY: @@ -2822,8 +2820,7 @@ row_sel_field_store_in_mysql_format_func( ut_ad(len * templ->mbmaxlen >= templ->mysql_col_len || (field_no == templ->icp_rec_field_no && field->prefix_len > 0) - || templ->rec_field_is_prefix - || !index->table->not_redundant()); + || templ->rec_field_is_prefix); ut_ad(templ->is_virtual || !(field->prefix_len % templ->mbmaxlen)); @@ -2845,6 +2842,8 @@ row_sel_field_store_in_mysql_format_func( ut_ad(0); /* fall through */ + case DATA_CHAR: + case DATA_FIXBINARY: case DATA_FLOAT: case DATA_DOUBLE: case DATA_DECIMAL: @@ -2859,18 +2858,13 @@ row_sel_field_store_in_mysql_format_func( case DATA_INT: /* Convert InnoDB big-endian integer to little-endian format, sign bit restored to 2's complement form */ - DBUG_ASSERT(templ->mysql_col_len >= len); + DBUG_ASSERT(templ->mysql_col_len == len); byte* ptr = pad; do *--ptr = *data++; while (ptr != dest); - byte b = templ->is_unsigned || !((pad[-1] ^= 0x80) & 0x80) - ? 0 : 0xff; - - if (ulint l = templ->mysql_col_len - len) { - DBUG_ASSERT(!index->table->not_redundant()); - memset(pad, b, l); + if (!templ->is_unsigned) { + pad[-1] ^= 0x80; } - break; } }