mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
MDEV-15564 Avoid table rebuild in ALTER TABLE on collation or charset changes
Allow ALGORITHM=INSTANT (or avoid touching any data) when changing the collation, or in some cases, the character set, of a non-indexed CHAR or VARCHAR column. There is no penalty for subsequent DDL or DML operations, and compatibility with older MariaDB versions will be unaffected. Character sets may be changed when the old encoding is compatible with the new one. For example, changing from ASCII to anything ASCII-based, or from 3-byte to 4-byte UTF-8 can sometimes be performed instantly. This is joint work with Eugene Kosov. The test cases as well as ALTER_CONVERT_TO, charsets_are_compatible(), Type_handler::Charsets_are_compatible() are his work. The Field_str::is_equal(), Field_varstring::is_equal() and the InnoDB changes were mostly rewritten by me due to conflicts with MDEV-15563. Limitations: Changes of indexed columns will still require ALGORITHM=COPY. We should allow ALGORITHM=NOCOPY and allow the indexes to be rebuilt inside the storage engine, without copying the entire table. Instant column size changes (in bytes) are not supported by all storage engines. Instant CHAR column changes are only allowed for InnoDB ROW_FORMAT=REDUNDANT. We could allow this for InnoDB when the CHAR internally uses a variable-length encoding, say, when converting from 3-byte UTF-8 to 4-byte UTF-8. Instant VARCHAR column changes are allowed for InnoDB ROW_FORMAT=REDUNDANT, and for others only if the size in bytes does not change from 128..255 bytes to more than 256 bytes. Inside InnoDB, this slightly changes the way how MDEV-15563 works and fixes the result of the innodb.instant_alter_extend test. We change the way how ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT is handled. All column extension, type changes and renaming now go through a common route, except when ctx->is_instant() is in effect, for example, instant ADD or DROP COLUMN has been initiated. Only in that case we will go through innobase_instant_try() and rewrite all column metadata. get_type(field, prtype, mtype, len): Convert a SQL data type into InnoDB column metadata. innobase_rename_column_try(): Remove the update of SYS_COLUMNS. innobase_rename_or_enlarge_column_try(): New function, replacing part of innobase_rename_column_try() and all of innobase_enlarge_column_try(). Also changes column types. innobase_rename_or_enlarge_columns_cache(): Also change the column type.
This commit is contained in:
parent
e5701d8363
commit
ea0be9e2d6
13 changed files with 2674 additions and 205 deletions
|
|
@ -0,0 +1,28 @@
|
||||||
|
--- 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,
|
||||||
|
algorithm=instant;
|
||||||
|
-ERROR 0A000: ALGORITHM=INSTANT is not supported. Reason: Cannot change column type INPLACE. Try ALGORITHM=COPY
|
||||||
|
alter table boundary_255
|
||||||
|
modify c varchar(300) charset utf8mb3,
|
||||||
|
algorithm=instant;
|
||||||
1812
mysql-test/suite/innodb/r/instant_alter_charset.result
Normal file
1812
mysql-test/suite/innodb/r/instant_alter_charset.result
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -13,8 +13,8 @@
|
||||||
test.t check status OK
|
test.t check status OK
|
||||||
call check_table('t');
|
call check_table('t');
|
||||||
name mtype prtype len
|
name mtype prtype len
|
||||||
-a 2 800FE 200
|
-a 2 800FE 220
|
||||||
+a 13 2100FE 600
|
+a 13 2100FE 660
|
||||||
# Convert from VARCHAR to a bigger CHAR
|
# Convert from VARCHAR to a bigger CHAR
|
||||||
alter table t modify a varchar(200), algorithm=instant;
|
alter table t modify a varchar(200), 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: Cannot change column type INPLACE. Try ALGORITHM=COPY
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ Table Op Msg_type Msg_text
|
||||||
test.t check status OK
|
test.t check status OK
|
||||||
call check_table('t');
|
call check_table('t');
|
||||||
name mtype prtype len
|
name mtype prtype len
|
||||||
a 2 800FE 200
|
a 2 800FE 220
|
||||||
# Convert from VARCHAR to a bigger CHAR
|
# Convert from VARCHAR to a bigger CHAR
|
||||||
alter table t modify a varchar(200), algorithm=instant;
|
alter table t modify a varchar(200), 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: Cannot change column type INPLACE. Try ALGORITHM=COPY
|
||||||
|
|
@ -101,7 +101,7 @@ Table Op Msg_type Msg_text
|
||||||
test.t check status OK
|
test.t check status OK
|
||||||
call check_table('t');
|
call check_table('t');
|
||||||
name mtype prtype len
|
name mtype prtype len
|
||||||
a 3 3F04FE 200
|
a 3 3F04FE 220
|
||||||
# Convert from VARBINARY to a bigger BINARY
|
# Convert from VARBINARY to a bigger BINARY
|
||||||
alter table t modify a varbinary(220), algorithm=instant;
|
alter table t modify a varbinary(220), 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: Cannot change column type INPLACE. Try ALGORITHM=COPY
|
||||||
|
|
|
||||||
538
mysql-test/suite/innodb/t/instant_alter_charset.test
Normal file
538
mysql-test/suite/innodb/t/instant_alter_charset.test
Normal file
|
|
@ -0,0 +1,538 @@
|
||||||
|
--source include/innodb_row_format.inc
|
||||||
|
#--source include/innodb_page_size.inc
|
||||||
|
|
||||||
|
--let $row_format= `SELECT @@GLOBAL.innodb_default_row_format`
|
||||||
|
set names utf8;
|
||||||
|
|
||||||
|
create table no_rebuild (
|
||||||
|
a char(150) charset utf8mb3 collate utf8mb3_general_ci
|
||||||
|
) engine=innodb;
|
||||||
|
create table rebuild (
|
||||||
|
a varchar(150) charset ascii
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
set @id = (select table_id from information_schema.innodb_sys_tables
|
||||||
|
where name = 'test/no_rebuild');
|
||||||
|
select name, prtype, len from information_schema.innodb_sys_columns
|
||||||
|
where table_id = @id;
|
||||||
|
select c.prtype, c.len from information_schema.innodb_sys_columns as c inner join information_schema.innodb_sys_tables t on c.table_id = t.table_id
|
||||||
|
where t.name = 'test/rebuild' and c.name = 'a';
|
||||||
|
alter table no_rebuild
|
||||||
|
change a a char(150) charset utf8mb3 collate utf8mb3_spanish_ci,
|
||||||
|
algorithm=inplace;
|
||||||
|
alter table rebuild
|
||||||
|
change a a varchar(150) charset latin1 not null default 'asdf',
|
||||||
|
algorithm=inplace;
|
||||||
|
select name, prtype, len from information_schema.innodb_sys_columns
|
||||||
|
where table_id = @id;
|
||||||
|
select c.prtype, c.len from information_schema.innodb_sys_columns as c inner join information_schema.innodb_sys_tables t on c.table_id = t.table_id
|
||||||
|
where t.name = 'test/rebuild' and c.name = 'a';
|
||||||
|
|
||||||
|
drop table no_rebuild, rebuild;
|
||||||
|
|
||||||
|
create table supported_types (
|
||||||
|
id int primary key auto_increment,
|
||||||
|
a varchar(150) charset ascii,
|
||||||
|
b text(150) charset ascii,
|
||||||
|
c text charset ascii,
|
||||||
|
d tinytext charset ascii,
|
||||||
|
e mediumtext charset ascii,
|
||||||
|
f longtext charset ascii
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
alter table supported_types
|
||||||
|
convert to charset latin1,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
drop table supported_types;
|
||||||
|
|
||||||
|
create table various_cases (
|
||||||
|
a char(150) charset ascii,
|
||||||
|
b varchar(150) as (a) virtual,
|
||||||
|
c varchar(150) as (a) persistent
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
alter table various_cases
|
||||||
|
change a a char(150) charset latin1,
|
||||||
|
algorithm=inplace;
|
||||||
|
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table various_cases
|
||||||
|
change a a varchar(222),
|
||||||
|
algorithm=inplace;
|
||||||
|
|
||||||
|
alter table various_cases
|
||||||
|
change b b varchar(150) as (a) virtual,
|
||||||
|
algorithm=inplace;
|
||||||
|
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED
|
||||||
|
alter table various_cases
|
||||||
|
change c c varchar(150) as (a) persistent,
|
||||||
|
algorithm=inplace;
|
||||||
|
|
||||||
|
# Can not grow storage in bytes from CHAR
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table various_cases
|
||||||
|
modify a char(150) charset utf8mb4,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
drop table various_cases;
|
||||||
|
|
||||||
|
|
||||||
|
create table all_texts (
|
||||||
|
a tinytext charset ascii,
|
||||||
|
b text charset ascii,
|
||||||
|
c mediumtext charset ascii,
|
||||||
|
d longtext charset ascii,
|
||||||
|
footer int
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
alter table all_texts
|
||||||
|
convert to charset latin1 collate latin1_general_ci,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
drop table all_texts;
|
||||||
|
|
||||||
|
|
||||||
|
create table all_binaries (
|
||||||
|
a tinyblob,
|
||||||
|
b blob,
|
||||||
|
c mediumblob,
|
||||||
|
d longblob,
|
||||||
|
e varbinary(150),
|
||||||
|
f binary(150)
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_binaries modify a tinytext, algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_binaries modify b text, algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_binaries modify c mediumtext, algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_binaries modify d longtext, algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_binaries modify e varchar(150), algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_binaries modify f char(150), algorithm=instant;
|
||||||
|
|
||||||
|
drop table all_binaries;
|
||||||
|
|
||||||
|
create table all_strings (
|
||||||
|
a tinytext,
|
||||||
|
b text,
|
||||||
|
c mediumtext,
|
||||||
|
d longtext,
|
||||||
|
e varchar(150),
|
||||||
|
f char(150)
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_strings modify a tinyblob, algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_strings modify b blob, algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_strings modify c mediumblob, algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_strings modify d longblob, algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_strings modify e varbinary(150), algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_strings modify f binary(150), algorithm=instant;
|
||||||
|
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_strings modify a tinytext charset binary, algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_strings modify b text charset binary, algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_strings modify c mediumtext charset binary, algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_strings modify d longtext charset binary, algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_strings modify e varchar(150) charset binary, algorithm=instant;
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table all_strings modify f char(150) charset binary, algorithm=instant;
|
||||||
|
|
||||||
|
drop table all_strings;
|
||||||
|
|
||||||
|
create table key_part_change (
|
||||||
|
a char(150) charset ascii,
|
||||||
|
b char(150) charset ascii,
|
||||||
|
c char(150) charset ascii,
|
||||||
|
unique key ab (a,b)
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table key_part_change
|
||||||
|
modify a char(150) charset utf8mb4,
|
||||||
|
drop index ab,
|
||||||
|
add unique key ab(a,c),
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
drop table key_part_change;
|
||||||
|
|
||||||
|
create table key_part_change_and_rename (
|
||||||
|
a char(100) charset ascii,
|
||||||
|
b char(100) charset ascii,
|
||||||
|
unique key ab (a,b)
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table key_part_change_and_rename
|
||||||
|
change a b char(100) charset utf8mb4,
|
||||||
|
change b a char(100) charset utf8mb4,
|
||||||
|
drop index ab,
|
||||||
|
add unique key ab(a,b),
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
drop table key_part_change_and_rename;
|
||||||
|
|
||||||
|
create table enum_and_set (
|
||||||
|
a enum('one', 'two') charset utf8mb3,
|
||||||
|
b set('three', 'four') charset utf8mb3
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table enum_and_set
|
||||||
|
modify a enum('one', 'two') charset utf8mb4,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table enum_and_set
|
||||||
|
modify b enum('three', 'four') charset utf8mb4,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
drop table enum_and_set;
|
||||||
|
|
||||||
|
create table compressed (
|
||||||
|
a varchar(255) charset utf8mb3 compressed
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
insert into compressed values ('AAA'), ('bbb'), ('CCC');
|
||||||
|
|
||||||
|
alter table compressed
|
||||||
|
modify a varchar(255) charset utf8mb4 compressed,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
select * from compressed;
|
||||||
|
check table compresed;
|
||||||
|
|
||||||
|
drop table compressed;
|
||||||
|
|
||||||
|
create table key_part_bug (
|
||||||
|
id int primary key auto_increment,
|
||||||
|
a varchar(150) charset utf8mb3 unique key
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
alter table key_part_bug
|
||||||
|
modify a varchar(150) charset utf8mb4,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
drop table key_part_bug;
|
||||||
|
|
||||||
|
|
||||||
|
create table latin1_swedish_special_case (
|
||||||
|
copy1 varchar(150) charset ascii collate ascii_general_ci,
|
||||||
|
copy2 char(150) charset ascii collate ascii_general_ci,
|
||||||
|
instant1 varchar(150) charset ascii collate ascii_general_ci,
|
||||||
|
instant2 char(150) charset ascii collate ascii_general_ci
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
select c.name, c.prtype, c.mtype, c.len from information_schema.innodb_sys_columns as c inner join information_schema.innodb_sys_tables t on c.table_id = t.table_id
|
||||||
|
where t.name = 'test/latin1_swedish_special_case';
|
||||||
|
alter table latin1_swedish_special_case
|
||||||
|
modify copy1 varchar(150) charset latin1 collate latin1_swedish_ci,
|
||||||
|
modify copy2 char(150) charset latin1 collate latin1_swedish_ci,
|
||||||
|
algorithm=copy;
|
||||||
|
alter table latin1_swedish_special_case
|
||||||
|
modify instant1 varchar(150) charset latin1 collate latin1_swedish_ci,
|
||||||
|
modify instant2 char(150) charset latin1 collate latin1_swedish_ci,
|
||||||
|
algorithm=instant;
|
||||||
|
select c.name, c.prtype, c.mtype, c.len from information_schema.innodb_sys_columns as c inner join information_schema.innodb_sys_tables t on c.table_id = t.table_id
|
||||||
|
where t.name = 'test/latin1_swedish_special_case';
|
||||||
|
alter table latin1_swedish_special_case
|
||||||
|
modify copy1 varchar(150) charset latin1 collate latin1_general_ci,
|
||||||
|
modify copy2 char(150) charset latin1 collate latin1_general_ci,
|
||||||
|
algorithm=copy;
|
||||||
|
alter table latin1_swedish_special_case
|
||||||
|
modify instant1 varchar(150) charset latin1 collate latin1_general_ci,
|
||||||
|
modify instant2 char(150) charset latin1 collate latin1_general_ci,
|
||||||
|
algorithm=instant;
|
||||||
|
select c.name, c.prtype, c.mtype, c.len from information_schema.innodb_sys_columns as c inner join information_schema.innodb_sys_tables t on c.table_id = t.table_id
|
||||||
|
where t.name = 'test/latin1_swedish_special_case';
|
||||||
|
|
||||||
|
drop table latin1_swedish_special_case;
|
||||||
|
|
||||||
|
create table regression (a varchar(100) charset utf8mb3 primary key, b int) engine=innodb;
|
||||||
|
alter table regression convert to character set utf8mb4;
|
||||||
|
drop table regression;
|
||||||
|
|
||||||
|
# ROW_FORMAT=DYNAMIC limitation:
|
||||||
|
# size in bytes cannot be increased from less of equal that 255 to more than 255
|
||||||
|
create table boundary_255 (
|
||||||
|
a varchar(50) charset ascii,
|
||||||
|
b varchar(200) charset ascii,
|
||||||
|
c varchar(300) charset ascii
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
alter table boundary_255
|
||||||
|
modify a varchar(50) charset utf8mb3,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
if ($row_format == 'redundant') {
|
||||||
|
alter table boundary_255
|
||||||
|
modify b varchar(200) charset utf8mb3,
|
||||||
|
algorithm=instant;
|
||||||
|
}
|
||||||
|
if ($row_format != 'redundant') {
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
alter table boundary_255
|
||||||
|
modify b varchar(200) charset utf8mb3,
|
||||||
|
algorithm=instant;
|
||||||
|
}
|
||||||
|
|
||||||
|
alter table boundary_255
|
||||||
|
modify c varchar(300) charset utf8mb3,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
drop table boundary_255;
|
||||||
|
|
||||||
|
create table fully_compatible (
|
||||||
|
id int auto_increment unique key,
|
||||||
|
from_charset char(255),
|
||||||
|
from_collate char(255),
|
||||||
|
to_charset char(255),
|
||||||
|
to_collate char(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
insert into fully_compatible (from_charset, from_collate, to_charset, to_collate) values
|
||||||
|
('utf8mb3', 'utf8mb3_general_ci', 'utf8mb4', 'utf8mb4_general_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_bin', 'utf8mb4', 'utf8mb4_bin'),
|
||||||
|
('utf8mb3', 'utf8mb3_unicode_ci', 'utf8mb4', 'utf8mb4_unicode_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_icelandic_ci', 'utf8mb4', 'utf8mb4_icelandic_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_latvian_ci', 'utf8mb4', 'utf8mb4_latvian_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_romanian_ci', 'utf8mb4', 'utf8mb4_romanian_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_slovenian_ci', 'utf8mb4', 'utf8mb4_slovenian_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_polish_ci', 'utf8mb4', 'utf8mb4_polish_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_estonian_ci', 'utf8mb4', 'utf8mb4_estonian_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_spanish_ci', 'utf8mb4', 'utf8mb4_spanish_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_swedish_ci', 'utf8mb4', 'utf8mb4_swedish_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_turkish_ci', 'utf8mb4', 'utf8mb4_turkish_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_czech_ci', 'utf8mb4', 'utf8mb4_czech_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_danish_ci', 'utf8mb4', 'utf8mb4_danish_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_lithuanian_ci', 'utf8mb4', 'utf8mb4_lithuanian_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_slovak_ci', 'utf8mb4', 'utf8mb4_slovak_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_spanish2_ci', 'utf8mb4', 'utf8mb4_spanish2_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_roman_ci', 'utf8mb4', 'utf8mb4_roman_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_persian_ci', 'utf8mb4', 'utf8mb4_persian_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_esperanto_ci', 'utf8mb4', 'utf8mb4_esperanto_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_hungarian_ci', 'utf8mb4', 'utf8mb4_hungarian_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_sinhala_ci', 'utf8mb4', 'utf8mb4_sinhala_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_german2_ci', 'utf8mb4', 'utf8mb4_german2_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_croatian_mysql561_ci', 'utf8mb4', 'utf8mb4_croatian_mysql561_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_unicode_520_ci', 'utf8mb4', 'utf8mb4_unicode_520_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_vietnamese_ci', 'utf8mb4', 'utf8mb4_vietnamese_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_croatian_ci', 'utf8mb4', 'utf8mb4_croatian_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_myanmar_ci', 'utf8mb4', 'utf8mb4_myanmar_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_thai_520_w2', 'utf8mb4', 'utf8mb4_thai_520_w2'),
|
||||||
|
('utf8mb3', 'utf8mb3_general_nopad_ci', 'utf8mb4', 'utf8mb4_general_nopad_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_nopad_bin', 'utf8mb4', 'utf8mb4_nopad_bin'),
|
||||||
|
('utf8mb3', 'utf8mb3_unicode_nopad_ci', 'utf8mb4', 'utf8mb4_unicode_nopad_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_unicode_520_nopad_ci', 'utf8mb4', 'utf8mb4_unicode_520_nopad_ci'),
|
||||||
|
|
||||||
|
('ucs2', 'ucs2_general_ci', 'utf16', 'utf16_general_ci'),
|
||||||
|
('ucs2', 'ucs2_unicode_ci', 'utf16', 'utf16_unicode_ci'),
|
||||||
|
('ucs2', 'ucs2_icelandic_ci', 'utf16', 'utf16_icelandic_ci'),
|
||||||
|
('ucs2', 'ucs2_latvian_ci', 'utf16', 'utf16_latvian_ci'),
|
||||||
|
('ucs2', 'ucs2_romanian_ci', 'utf16', 'utf16_romanian_ci'),
|
||||||
|
('ucs2', 'ucs2_slovenian_ci', 'utf16', 'utf16_slovenian_ci'),
|
||||||
|
('ucs2', 'ucs2_polish_ci', 'utf16', 'utf16_polish_ci'),
|
||||||
|
('ucs2', 'ucs2_estonian_ci', 'utf16', 'utf16_estonian_ci'),
|
||||||
|
('ucs2', 'ucs2_spanish_ci', 'utf16', 'utf16_spanish_ci'),
|
||||||
|
('ucs2', 'ucs2_general_ci', 'utf16', 'utf16_general_ci'),
|
||||||
|
|
||||||
|
('ascii', 'ascii_general_ci', 'utf8mb3', 'utf8mb3_general_ci'),
|
||||||
|
('ascii', 'ascii_general_ci', 'utf8mb4', 'utf8mb4_general_ci'),
|
||||||
|
('ascii', 'ascii_general_ci', 'latin1', 'latin1_general_ci'),
|
||||||
|
('ascii', 'ascii_bin', 'latin1', 'latin1_bin'),
|
||||||
|
('ascii', 'ascii_nopad_bin', 'latin1', 'latin1_nopad_bin'),
|
||||||
|
('ascii', 'ascii_general_ci', 'latin2', 'latin2_general_ci'),
|
||||||
|
('ascii', 'ascii_general_ci', 'latin7', 'latin7_general_ci'),
|
||||||
|
('ascii', 'ascii_bin', 'koi8u', 'koi8u_bin'),
|
||||||
|
('ascii', 'ascii_bin', 'ujis', 'ujis_bin'),
|
||||||
|
('ascii', 'ascii_bin', 'big5', 'big5_bin'),
|
||||||
|
('ascii', 'ascii_bin', 'gbk', 'gbk_bin')
|
||||||
|
;
|
||||||
|
|
||||||
|
let $data_size = `select count(*) from fully_compatible`;
|
||||||
|
let $counter = 1;
|
||||||
|
|
||||||
|
while ($counter <= $data_size) {
|
||||||
|
let $from_charset = `select from_charset from fully_compatible where id = $counter`;
|
||||||
|
let $from_collate = `select from_collate from fully_compatible where id = $counter`;
|
||||||
|
let $to_charset = `select to_charset from fully_compatible where id = $counter`;
|
||||||
|
let $to_collate = `select to_collate from fully_compatible where id = $counter`;
|
||||||
|
|
||||||
|
eval create table tmp (
|
||||||
|
a varchar(50) charset $from_charset collate $from_collate,
|
||||||
|
b varchar(50) charset $from_charset collate $from_collate primary key
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
insert into tmp values ('AAA', 'AAA'), ('bbb', 'bbb');
|
||||||
|
|
||||||
|
eval alter table tmp
|
||||||
|
change a a varchar(50) charset $to_charset collate $to_collate,
|
||||||
|
modify b varchar(50) charset $to_charset collate $to_collate,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
check table tmp;
|
||||||
|
|
||||||
|
drop table tmp;
|
||||||
|
|
||||||
|
inc $counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
drop table fully_compatible;
|
||||||
|
|
||||||
|
|
||||||
|
create table compatible_without_index (
|
||||||
|
id int auto_increment unique key,
|
||||||
|
from_charset char(255),
|
||||||
|
from_collate char(255),
|
||||||
|
to_charset char(255),
|
||||||
|
to_collate char(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
insert into compatible_without_index (from_charset, from_collate, to_charset, to_collate) values
|
||||||
|
('ascii', 'ascii_general_ci', 'utf8mb3', 'utf8mb3_swedish_ci'),
|
||||||
|
('ascii', 'ascii_bin', 'latin1', 'latin1_swedish_ci'),
|
||||||
|
('ascii', 'ascii_general_nopad_ci', 'latin1', 'latin1_swedish_ci'),
|
||||||
|
('ascii', 'ascii_nopad_bin', 'latin1', 'latin1_swedish_ci'),
|
||||||
|
|
||||||
|
('ascii', 'ascii_general_ci', 'koi8u', 'koi8u_bin'),
|
||||||
|
('ascii', 'ascii_general_nopad_ci', 'koi8u', 'koi8u_bin'),
|
||||||
|
('ascii', 'ascii_nopad_bin', 'koi8u', 'koi8u_bin'),
|
||||||
|
|
||||||
|
('ascii', 'ascii_general_ci', 'latin1', 'latin1_swedish_ci'),
|
||||||
|
('ascii', 'ascii_bin', 'utf8mb3', 'utf8mb3_swedish_ci'),
|
||||||
|
('ascii', 'ascii_general_nopad_ci', 'utf8mb3', 'utf8mb3_swedish_ci'),
|
||||||
|
('ascii', 'ascii_nopad_bin', 'utf8mb3', 'utf8mb3_swedish_ci'),
|
||||||
|
|
||||||
|
('ascii', 'ascii_general_ci', 'utf8mb4', 'utf8mb4_danish_ci'),
|
||||||
|
('ascii', 'ascii_bin', 'utf8mb4', 'utf8mb4_danish_ci'),
|
||||||
|
('ascii', 'ascii_general_nopad_ci', 'utf8mb4', 'utf8mb4_danish_ci'),
|
||||||
|
('ascii', 'ascii_nopad_bin', 'utf8mb4', 'utf8mb4_danish_ci'),
|
||||||
|
|
||||||
|
('utf8mb3', 'utf8mb3_general_ci', 'utf8mb4', 'utf8mb4_vietnamese_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_bin', 'utf8mb4', 'utf8mb4_vietnamese_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_general_nopad_ci', 'utf8mb4', 'utf8mb4_vietnamese_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_nopad_bin', 'utf8mb4', 'utf8mb4_vietnamese_ci'),
|
||||||
|
|
||||||
|
('ascii', 'ascii_general_ci', 'gbk', 'gbk_chinese_ci'),
|
||||||
|
('ascii', 'ascii_general_ci', 'gbk', 'gbk_chinese_nopad_ci'),
|
||||||
|
|
||||||
|
('ucs2', 'ucs2_myanmar_ci', 'utf16', 'utf16_thai_520_w2'),
|
||||||
|
('ucs2', 'ucs2_general_ci', 'utf16', 'utf16_unicode_nopad_ci'),
|
||||||
|
('ucs2', 'ucs2_general_mysql500_ci', 'utf16', 'utf16_spanish2_ci'),
|
||||||
|
|
||||||
|
('ascii', 'ascii_general_ci', 'ascii', 'ascii_bin'),
|
||||||
|
('utf8mb3', 'utf8mb3_roman_ci', 'utf8mb3', 'utf8mb3_lithuanian_ci'),
|
||||||
|
('utf8mb4', 'utf8mb4_thai_520_w2', 'utf8mb4', 'utf8mb4_persian_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_myanmar_ci', 'utf8mb4', 'utf8mb4_german2_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_general_ci', 'utf8mb3', 'utf8mb3_unicode_ci'),
|
||||||
|
('latin1', 'latin1_general_cs', 'latin1', 'latin1_general_ci'),
|
||||||
|
('ascii', 'ascii_general_ci', 'ujis', 'ujis_japanese_ci'),
|
||||||
|
('ascii', 'ascii_general_ci', 'big5', 'big5_chinese_ci'),
|
||||||
|
('ascii', 'ascii_general_ci', 'latin2', 'latin2_croatian_ci'),
|
||||||
|
('ascii', 'ascii_general_ci', 'latin7', 'latin7_estonian_cs'),
|
||||||
|
('utf16', 'utf16_general_ci', 'utf16', 'utf16_german2_ci')
|
||||||
|
;
|
||||||
|
|
||||||
|
let $data_size = `select count(*) from compatible_without_index`;
|
||||||
|
let $counter = 1;
|
||||||
|
|
||||||
|
while ($counter <= $data_size) {
|
||||||
|
let $from_charset = `select from_charset from compatible_without_index where id = $counter`;
|
||||||
|
let $from_collate = `select from_collate from compatible_without_index where id = $counter`;
|
||||||
|
let $to_charset = `select to_charset from compatible_without_index where id = $counter`;
|
||||||
|
let $to_collate = `select to_collate from compatible_without_index where id = $counter`;
|
||||||
|
|
||||||
|
eval create table tmp (
|
||||||
|
a varchar(50) charset $from_charset collate $from_collate,
|
||||||
|
b varchar(50) charset $from_charset collate $from_collate unique key,
|
||||||
|
c varchar(50) charset $from_charset collate $from_collate primary key
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
eval alter table tmp
|
||||||
|
change a a varchar(50) charset $to_charset collate $to_collate,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
eval alter table tmp
|
||||||
|
modify b varchar(50) charset $to_charset collate $to_collate,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
eval alter table tmp
|
||||||
|
modify c varchar(50) charset $to_charset collate $to_collate,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
drop table tmp;
|
||||||
|
|
||||||
|
inc $counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
drop table compatible_without_index;
|
||||||
|
|
||||||
|
|
||||||
|
create table fully_incompatible (
|
||||||
|
id int auto_increment unique key,
|
||||||
|
from_charset char(255),
|
||||||
|
from_collate char(255),
|
||||||
|
to_charset char(255),
|
||||||
|
to_collate char(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
insert into fully_incompatible (from_charset, from_collate, to_charset, to_collate) values
|
||||||
|
('utf8mb4', 'utf8mb4_general_ci', 'utf8mb3', 'utf8mb3_general_ci'),
|
||||||
|
('utf8mb4', 'utf8mb4_general_ci', 'ascii', 'ascii_general_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_general_ci', 'ascii', 'ascii_general_ci'),
|
||||||
|
('utf8mb3', 'utf8mb3_general_ci', 'latin1', 'latin1_general_ci'),
|
||||||
|
('utf16', 'utf16_general_ci', 'utf32', 'utf32_general_ci'),
|
||||||
|
('latin1', 'latin1_general_ci', 'ascii', 'ascii_general_ci'),
|
||||||
|
('ascii', 'ascii_general_ci', 'swe7', 'swe7_swedish_ci'),
|
||||||
|
('eucjpms', 'eucjpms_japanese_nopad_ci', 'geostd8', 'geostd8_general_ci'),
|
||||||
|
('latin1', 'latin1_general_ci', 'utf16', 'utf16_general_ci')
|
||||||
|
;
|
||||||
|
|
||||||
|
let $data_size = `select count(*) from fully_incompatible`;
|
||||||
|
let $counter = 1;
|
||||||
|
|
||||||
|
while ($counter <= $data_size) {
|
||||||
|
let $from_charset = `select from_charset from fully_incompatible where id = $counter`;
|
||||||
|
let $from_collate = `select from_collate from fully_incompatible where id = $counter`;
|
||||||
|
let $to_charset = `select to_charset from fully_incompatible where id = $counter`;
|
||||||
|
let $to_collate = `select to_collate from fully_incompatible where id = $counter`;
|
||||||
|
|
||||||
|
eval create table tmp (
|
||||||
|
a varchar(150) charset $from_charset collate $from_collate,
|
||||||
|
b text(150) charset $from_charset collate $from_collate,
|
||||||
|
unique key b_idx (b(150))
|
||||||
|
) engine=innodb;
|
||||||
|
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
eval alter table tmp
|
||||||
|
change a a varchar(150) charset $to_charset collate $to_collate,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
--error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON
|
||||||
|
eval alter table tmp
|
||||||
|
modify b text charset $to_charset collate $to_collate,
|
||||||
|
algorithm=instant;
|
||||||
|
|
||||||
|
drop table tmp;
|
||||||
|
|
||||||
|
inc $counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
drop table fully_incompatible;
|
||||||
|
|
@ -36,18 +36,15 @@ alter table t modify a char(255), algorithm=instant;
|
||||||
alter table t modify a char(255), algorithm=copy;
|
alter table t modify a char(255), algorithm=copy;
|
||||||
|
|
||||||
create or replace table t (a varchar(200));
|
create or replace table t (a varchar(200));
|
||||||
if ($have_debug) {
|
|
||||||
--disable_query_log
|
|
||||||
--disable_result_log
|
|
||||||
set debug_dbug= '+d,ib_instant_error';
|
|
||||||
--error ER_RECORD_FILE_FULL
|
|
||||||
alter table t modify a char(200);
|
|
||||||
set debug_dbug= default;
|
|
||||||
--enable_query_log
|
|
||||||
--enable_result_log
|
|
||||||
}
|
|
||||||
insert into t values (@bigval);
|
insert into t values (@bigval);
|
||||||
insert into t values ('z');
|
insert into t values ('z');
|
||||||
|
if ($have_debug) {
|
||||||
|
--disable_query_log
|
||||||
|
# This should not be reachable.
|
||||||
|
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;
|
alter table t modify a char(200), algorithm=instant;
|
||||||
select count(a) from t where a = @bigval;
|
select count(a) from t where a = @bigval;
|
||||||
select a, length(a) from t where a = 'z';
|
select a, length(a) from t where a = 'z';
|
||||||
|
|
@ -82,16 +79,6 @@ alter table t modify a binary(255), algorithm=instant;
|
||||||
alter table t modify a binary(255), algorithm=copy;
|
alter table t modify a binary(255), algorithm=copy;
|
||||||
|
|
||||||
create or replace table t (a varbinary(200));
|
create or replace table t (a varbinary(200));
|
||||||
if ($have_debug) {
|
|
||||||
--disable_query_log
|
|
||||||
--disable_result_log
|
|
||||||
set debug_dbug= '+d,ib_instant_error';
|
|
||||||
--error ER_RECORD_FILE_FULL
|
|
||||||
alter table t modify a binary(200);
|
|
||||||
set debug_dbug= default;
|
|
||||||
--enable_query_log
|
|
||||||
--enable_result_log
|
|
||||||
}
|
|
||||||
insert into t values (@bigval);
|
insert into t values (@bigval);
|
||||||
insert into t values ('z');
|
insert into t values ('z');
|
||||||
alter table t modify a binary(200), algorithm=instant;
|
alter table t modify a binary(200), algorithm=instant;
|
||||||
|
|
@ -122,16 +109,6 @@ call check_table('t');
|
||||||
|
|
||||||
--echo # Integer conversions
|
--echo # Integer conversions
|
||||||
create or replace table t (x tinyint);
|
create or replace table t (x tinyint);
|
||||||
if ($have_debug) {
|
|
||||||
--disable_query_log
|
|
||||||
--disable_result_log
|
|
||||||
set debug_dbug= '+d,ib_instant_error';
|
|
||||||
--error ER_RECORD_FILE_FULL
|
|
||||||
alter table t modify x smallint;
|
|
||||||
set debug_dbug= default;
|
|
||||||
--enable_query_log
|
|
||||||
--enable_result_log
|
|
||||||
}
|
|
||||||
insert into t values (127);
|
insert into t values (127);
|
||||||
alter table t modify x smallint, algorithm=instant;
|
alter table t modify x smallint, algorithm=instant;
|
||||||
select * from t;
|
select * from t;
|
||||||
|
|
@ -156,6 +133,13 @@ select * from t;
|
||||||
check table t extended;
|
check table t extended;
|
||||||
call check_table('t');
|
call check_table('t');
|
||||||
|
|
||||||
|
if ($have_debug) {
|
||||||
|
--disable_query_log
|
||||||
|
# This should not be reachable.
|
||||||
|
set debug_dbug= @save_debug;
|
||||||
|
--enable_query_log
|
||||||
|
}
|
||||||
|
|
||||||
--echo # Check IMPORT TABLESPACE
|
--echo # Check IMPORT TABLESPACE
|
||||||
--let $MYSQLD_DATADIR= `select @@datadir`
|
--let $MYSQLD_DATADIR= `select @@datadir`
|
||||||
create or replace table t2 (x int);
|
create or replace table t2 (x int);
|
||||||
|
|
|
||||||
101
sql/field.cc
101
sql/field.cc
|
|
@ -7068,15 +7068,25 @@ uint Field::is_equal(Create_field *new_field)
|
||||||
|
|
||||||
uint Field_str::is_equal(Create_field *new_field)
|
uint Field_str::is_equal(Create_field *new_field)
|
||||||
{
|
{
|
||||||
if (new_field->type_handler() == type_handler() &&
|
if (new_field->type_handler() != type_handler())
|
||||||
new_field->charset == field_charset)
|
return IS_EQUAL_NO;
|
||||||
{
|
if (new_field->length < max_display_length())
|
||||||
if (new_field->length == max_display_length())
|
return IS_EQUAL_NO;
|
||||||
return IS_EQUAL_YES;
|
if (new_field->char_length < char_length())
|
||||||
if (new_field->length > max_display_length() &&
|
return IS_EQUAL_NO;
|
||||||
(table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION))
|
|
||||||
return IS_EQUAL_PACK_LENGTH_EXT;
|
const bool part_of_a_key= !new_field->field->part_of_key.is_clear_all();
|
||||||
}
|
if (!Type_handler::Charsets_are_compatible(field_charset, new_field->charset,
|
||||||
|
part_of_a_key))
|
||||||
|
return IS_EQUAL_NO;
|
||||||
|
|
||||||
|
if (new_field->length == max_display_length())
|
||||||
|
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;
|
return IS_EQUAL_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7915,27 +7925,34 @@ uint Field_varstring::is_equal(Create_field *new_field)
|
||||||
{
|
{
|
||||||
if (new_field->length < field_length)
|
if (new_field->length < field_length)
|
||||||
return IS_EQUAL_NO;
|
return IS_EQUAL_NO;
|
||||||
|
if (new_field->char_length < char_length())
|
||||||
|
return IS_EQUAL_NO;
|
||||||
|
if (!new_field->compression_method() != !compression_method())
|
||||||
|
return IS_EQUAL_NO;
|
||||||
|
|
||||||
if (new_field->charset == field_charset &&
|
bool part_of_a_key= !new_field->field->part_of_key.is_clear_all();
|
||||||
!new_field->compression_method() == !compression_method())
|
if (!Type_handler::Charsets_are_compatible(field_charset, new_field->charset,
|
||||||
|
part_of_a_key))
|
||||||
|
return IS_EQUAL_NO;
|
||||||
|
|
||||||
|
const Type_handler *new_type_handler= new_field->type_handler();
|
||||||
|
if (new_type_handler == type_handler())
|
||||||
{
|
{
|
||||||
const Type_handler *new_type_handler= new_field->type_handler();
|
if (new_field->length == field_length)
|
||||||
if (new_type_handler == type_handler())
|
return new_field->charset == field_charset
|
||||||
{
|
? IS_EQUAL_YES : IS_EQUAL_PACK_LENGTH;
|
||||||
if (new_field->length == field_length)
|
if (field_length <= 127 ||
|
||||||
return IS_EQUAL_YES;
|
new_field->length <= 255 ||
|
||||||
if (field_length <= 127 ||
|
field_length > 255 ||
|
||||||
new_field->length <= 255 ||
|
(table->file->ha_table_flags() & HA_EXTENDED_TYPES_CONVERSION))
|
||||||
field_length > 255 ||
|
return IS_EQUAL_PACK_LENGTH; // VARCHAR, longer length
|
||||||
(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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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;
|
return IS_EQUAL_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -8702,10 +8719,32 @@ uint Field_blob::max_packed_col_length(uint max_length)
|
||||||
|
|
||||||
uint Field_blob::is_equal(Create_field *new_field)
|
uint Field_blob::is_equal(Create_field *new_field)
|
||||||
{
|
{
|
||||||
return new_field->type_handler() == type_handler() &&
|
if (new_field->type_handler() != type_handler())
|
||||||
new_field->charset == field_charset &&
|
{
|
||||||
new_field->pack_length == pack_length() &&
|
return IS_EQUAL_NO;
|
||||||
!new_field->compression_method() == !compression_method();
|
}
|
||||||
|
if (!new_field->compression_method() != !compression_method())
|
||||||
|
{
|
||||||
|
return IS_EQUAL_NO;
|
||||||
|
}
|
||||||
|
if (new_field->pack_length != pack_length())
|
||||||
|
{
|
||||||
|
return IS_EQUAL_NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool part_of_a_key= !new_field->field->part_of_key.is_clear_all();
|
||||||
|
if (!Type_handler::Charsets_are_compatible(field_charset, new_field->charset,
|
||||||
|
part_of_a_key))
|
||||||
|
{
|
||||||
|
return IS_EQUAL_NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field_charset != new_field->charset)
|
||||||
|
{
|
||||||
|
return IS_EQUAL_PACK_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IS_EQUAL_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -627,6 +627,8 @@ typedef ulonglong alter_table_operations;
|
||||||
#define ALTER_KEYS_ONOFF (1ULL << 9)
|
#define ALTER_KEYS_ONOFF (1ULL << 9)
|
||||||
// Set for FORCE, ENGINE(same engine), by mysql_recreate_table()
|
// Set for FORCE, ENGINE(same engine), by mysql_recreate_table()
|
||||||
#define ALTER_RECREATE (1ULL << 10)
|
#define ALTER_RECREATE (1ULL << 10)
|
||||||
|
// Set for CONVERT TO
|
||||||
|
#define ALTER_CONVERT_TO (1ULL << 11)
|
||||||
// Set for ADD FOREIGN KEY
|
// Set for ADD FOREIGN KEY
|
||||||
#define ALTER_ADD_FOREIGN_KEY (1ULL << 21)
|
#define ALTER_ADD_FOREIGN_KEY (1ULL << 21)
|
||||||
// Set for DROP FOREIGN KEY
|
// Set for DROP FOREIGN KEY
|
||||||
|
|
|
||||||
|
|
@ -8195,3 +8195,49 @@ Type_handler_timestamp_common::Item_param_val_native(THD *thd,
|
||||||
item->get_date(thd, <ime, Datetime::Options(TIME_NO_ZERO_IN_DATE, thd)) ||
|
item->get_date(thd, <ime, Datetime::Options(TIME_NO_ZERO_IN_DATE, thd)) ||
|
||||||
TIME_to_native(thd, <ime, to, item->datetime_precision(thd));
|
TIME_to_native(thd, <ime, to, item->datetime_precision(thd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool charsets_are_compatible(const char *old_cs_name,
|
||||||
|
const CHARSET_INFO *new_ci)
|
||||||
|
{
|
||||||
|
const char *new_cs_name= new_ci->csname;
|
||||||
|
|
||||||
|
if (!strcmp(old_cs_name, new_cs_name))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!strcmp(old_cs_name, MY_UTF8MB3) && !strcmp(new_cs_name, MY_UTF8MB4))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!strcmp(old_cs_name, "ascii") && !(new_ci->state & MY_CS_NONASCII))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!strcmp(old_cs_name, "ucs2") && !strcmp(new_cs_name, "utf16"))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Type_handler::Charsets_are_compatible(const CHARSET_INFO *old_ci,
|
||||||
|
const CHARSET_INFO *new_ci,
|
||||||
|
bool part_of_a_key)
|
||||||
|
{
|
||||||
|
const char *old_cs_name= old_ci->csname;
|
||||||
|
const char *new_cs_name= new_ci->csname;
|
||||||
|
|
||||||
|
if (!charsets_are_compatible(old_cs_name, new_ci))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!part_of_a_key)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strcmp(old_ci->name + strlen(old_cs_name),
|
||||||
|
new_ci->name + strlen(new_cs_name)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3672,6 +3672,10 @@ public:
|
||||||
|
|
||||||
virtual bool
|
virtual bool
|
||||||
Vers_history_point_resolve_unit(THD *thd, Vers_history_point *point) const;
|
Vers_history_point_resolve_unit(THD *thd, Vers_history_point *point) const;
|
||||||
|
|
||||||
|
static bool Charsets_are_compatible(const CHARSET_INFO *old_ci,
|
||||||
|
const CHARSET_INFO *new_ci,
|
||||||
|
bool part_of_a_key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8447,7 +8447,7 @@ alter_list_item:
|
||||||
$5->name, $4->csname));
|
$5->name, $4->csname));
|
||||||
if (unlikely(Lex->create_info.add_alter_list_item_convert_to_charset($5)))
|
if (unlikely(Lex->create_info.add_alter_list_item_convert_to_charset($5)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
Lex->alter_info.flags|= ALTER_OPTIONS;
|
Lex->alter_info.flags|= ALTER_CONVERT_TO;
|
||||||
}
|
}
|
||||||
| create_table_options_space_separated
|
| create_table_options_space_separated
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8474,7 +8474,7 @@ alter_list_item:
|
||||||
$5->name, $4->csname));
|
$5->name, $4->csname));
|
||||||
if (unlikely(Lex->create_info.add_alter_list_item_convert_to_charset($5)))
|
if (unlikely(Lex->create_info.add_alter_list_item_convert_to_charset($5)))
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
Lex->alter_info.flags|= ALTER_OPTIONS;
|
Lex->alter_info.flags|= ALTER_CONVERT_TO;
|
||||||
}
|
}
|
||||||
| create_table_options_space_separated
|
| create_table_options_space_separated
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,6 @@ static const alter_table_operations INNOBASE_ALTER_REBUILD
|
||||||
| ALTER_OPTIONS
|
| ALTER_OPTIONS
|
||||||
/* ALTER_OPTIONS needs to check alter_options_need_rebuild() */
|
/* ALTER_OPTIONS needs to check alter_options_need_rebuild() */
|
||||||
| ALTER_COLUMN_NULLABLE
|
| ALTER_COLUMN_NULLABLE
|
||||||
| ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
|
|
||||||
| INNOBASE_DEFAULTS
|
| INNOBASE_DEFAULTS
|
||||||
| ALTER_STORED_COLUMN_ORDER
|
| ALTER_STORED_COLUMN_ORDER
|
||||||
| ALTER_DROP_STORED_COLUMN
|
| ALTER_DROP_STORED_COLUMN
|
||||||
|
|
@ -105,6 +104,7 @@ static const alter_table_operations INNOBASE_INPLACE_IGNORE
|
||||||
| ALTER_PARTITIONED
|
| ALTER_PARTITIONED
|
||||||
| ALTER_COLUMN_COLUMN_FORMAT
|
| ALTER_COLUMN_COLUMN_FORMAT
|
||||||
| ALTER_COLUMN_STORAGE_TYPE
|
| ALTER_COLUMN_STORAGE_TYPE
|
||||||
|
| ALTER_CONVERT_TO
|
||||||
| ALTER_VIRTUAL_GCOL_EXPR
|
| ALTER_VIRTUAL_GCOL_EXPR
|
||||||
| ALTER_DROP_CHECK_CONSTRAINT
|
| ALTER_DROP_CHECK_CONSTRAINT
|
||||||
| ALTER_RENAME
|
| ALTER_RENAME
|
||||||
|
|
@ -135,6 +135,7 @@ static const alter_table_operations INNOBASE_ALTER_INSTANT
|
||||||
| ALTER_ADD_VIRTUAL_COLUMN
|
| ALTER_ADD_VIRTUAL_COLUMN
|
||||||
| INNOBASE_FOREIGN_OPERATIONS
|
| INNOBASE_FOREIGN_OPERATIONS
|
||||||
| ALTER_COLUMN_EQUAL_PACK_LENGTH
|
| ALTER_COLUMN_EQUAL_PACK_LENGTH
|
||||||
|
| ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
|
||||||
| ALTER_COLUMN_UNVERSIONED
|
| ALTER_COLUMN_UNVERSIONED
|
||||||
| ALTER_DROP_VIRTUAL_COLUMN;
|
| ALTER_DROP_VIRTUAL_COLUMN;
|
||||||
|
|
||||||
|
|
@ -1507,8 +1508,7 @@ instant_alter_column_possible(
|
||||||
= ALTER_ADD_STORED_BASE_COLUMN
|
= ALTER_ADD_STORED_BASE_COLUMN
|
||||||
| ALTER_DROP_STORED_COLUMN
|
| ALTER_DROP_STORED_COLUMN
|
||||||
| ALTER_STORED_COLUMN_ORDER
|
| ALTER_STORED_COLUMN_ORDER
|
||||||
| ALTER_COLUMN_NULLABLE
|
| ALTER_COLUMN_NULLABLE;
|
||||||
| ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT;
|
|
||||||
|
|
||||||
if (!(ha_alter_info->handler_flags & avoid_rebuild)) {
|
if (!(ha_alter_info->handler_flags & avoid_rebuild)) {
|
||||||
alter_table_operations flags = ha_alter_info->handler_flags
|
alter_table_operations flags = ha_alter_info->handler_flags
|
||||||
|
|
@ -1551,7 +1551,6 @@ instant_alter_column_possible(
|
||||||
& ~ALTER_STORED_COLUMN_ORDER
|
& ~ALTER_STORED_COLUMN_ORDER
|
||||||
& ~ALTER_ADD_STORED_BASE_COLUMN
|
& ~ALTER_ADD_STORED_BASE_COLUMN
|
||||||
& ~ALTER_COLUMN_NULLABLE
|
& ~ALTER_COLUMN_NULLABLE
|
||||||
& ~ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
|
|
||||||
& ~ALTER_OPTIONS)) {
|
& ~ALTER_OPTIONS)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -5486,8 +5485,7 @@ static bool innobase_instant_try(
|
||||||
trx_t* trx)
|
trx_t* trx)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(!ctx->need_rebuild());
|
DBUG_ASSERT(!ctx->need_rebuild());
|
||||||
|
DBUG_ASSERT(ctx->is_instant());
|
||||||
if (!ctx->is_instant()) return false;
|
|
||||||
|
|
||||||
dict_table_t* user_table = ctx->old_table;
|
dict_table_t* user_table = ctx->old_table;
|
||||||
|
|
||||||
|
|
@ -8737,7 +8735,6 @@ innobase_drop_foreign_try(
|
||||||
@param[in] user_table InnoDB table that was being altered
|
@param[in] user_table InnoDB table that was being altered
|
||||||
@param[in] trx data dictionary transaction
|
@param[in] trx data dictionary transaction
|
||||||
@param[in] table_name Table name in MySQL
|
@param[in] table_name Table name in MySQL
|
||||||
@param[in] nth_col 0-based index of the column
|
|
||||||
@param[in] from old column name
|
@param[in] from old column name
|
||||||
@param[in] to new column name
|
@param[in] to new column name
|
||||||
@param[in] new_clustered whether the table has been rebuilt
|
@param[in] new_clustered whether the table has been rebuilt
|
||||||
|
|
@ -8750,7 +8747,6 @@ innobase_rename_column_try(
|
||||||
const dict_table_t* user_table,
|
const dict_table_t* user_table,
|
||||||
trx_t* trx,
|
trx_t* trx,
|
||||||
const char* table_name,
|
const char* table_name,
|
||||||
ulint nth_col,
|
|
||||||
const char* from,
|
const char* from,
|
||||||
const char* to,
|
const char* to,
|
||||||
bool new_clustered)
|
bool new_clustered)
|
||||||
|
|
@ -8770,33 +8766,7 @@ innobase_rename_column_try(
|
||||||
}
|
}
|
||||||
|
|
||||||
info = pars_info_create();
|
info = pars_info_create();
|
||||||
|
error = DB_SUCCESS;
|
||||||
pars_info_add_ull_literal(info, "tableid", user_table->id);
|
|
||||||
pars_info_add_int4_literal(info, "nth", nth_col);
|
|
||||||
pars_info_add_str_literal(info, "new", to);
|
|
||||||
|
|
||||||
trx->op_info = "renaming column in SYS_COLUMNS";
|
|
||||||
|
|
||||||
error = que_eval_sql(
|
|
||||||
info,
|
|
||||||
"PROCEDURE RENAME_SYS_COLUMNS_PROC () IS\n"
|
|
||||||
"BEGIN\n"
|
|
||||||
"UPDATE SYS_COLUMNS SET NAME=:new\n"
|
|
||||||
"WHERE TABLE_ID=:tableid\n"
|
|
||||||
"AND POS=:nth;\n"
|
|
||||||
"END;\n",
|
|
||||||
FALSE, trx);
|
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("ib_rename_column_error",
|
|
||||||
error = DB_OUT_OF_FILE_SPACE;);
|
|
||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
|
||||||
err_exit:
|
|
||||||
my_error_innodb(error, table_name, 0);
|
|
||||||
trx->error_state = DB_SUCCESS;
|
|
||||||
trx->op_info = "";
|
|
||||||
DBUG_RETURN(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
trx->op_info = "renaming column in SYS_FIELDS";
|
trx->op_info = "renaming column in SYS_FIELDS";
|
||||||
|
|
||||||
|
|
@ -8839,6 +8809,8 @@ err_exit:
|
||||||
"AND POS=:nth;\n"
|
"AND POS=:nth;\n"
|
||||||
"END;\n",
|
"END;\n",
|
||||||
FALSE, trx);
|
FALSE, trx);
|
||||||
|
DBUG_EXECUTE_IF("ib_rename_column_error",
|
||||||
|
error = DB_OUT_OF_FILE_SPACE;);
|
||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
if (error != DB_SUCCESS) {
|
||||||
goto err_exit;
|
goto err_exit;
|
||||||
|
|
@ -8846,6 +8818,14 @@ err_exit:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (error != DB_SUCCESS) {
|
||||||
|
err_exit:
|
||||||
|
my_error_innodb(error, table_name, 0);
|
||||||
|
trx->error_state = DB_SUCCESS;
|
||||||
|
trx->op_info = "";
|
||||||
|
DBUG_RETURN(true);
|
||||||
|
}
|
||||||
|
|
||||||
rename_foreign:
|
rename_foreign:
|
||||||
trx->op_info = "renaming column in SYS_FOREIGN_COLS";
|
trx->op_info = "renaming column in SYS_FOREIGN_COLS";
|
||||||
|
|
||||||
|
|
@ -8968,6 +8948,7 @@ innobase_rename_columns_try(
|
||||||
ulint num_v = 0;
|
ulint num_v = 0;
|
||||||
|
|
||||||
DBUG_ASSERT(ctx);
|
DBUG_ASSERT(ctx);
|
||||||
|
DBUG_ASSERT(ctx->need_rebuild());
|
||||||
DBUG_ASSERT(ha_alter_info->handler_flags
|
DBUG_ASSERT(ha_alter_info->handler_flags
|
||||||
& ALTER_COLUMN_NAME);
|
& ALTER_COLUMN_NAME);
|
||||||
|
|
||||||
|
|
@ -8981,17 +8962,10 @@ innobase_rename_columns_try(
|
||||||
cf_it.rewind();
|
cf_it.rewind();
|
||||||
while (Create_field* cf = cf_it++) {
|
while (Create_field* cf = cf_it++) {
|
||||||
if (cf->field == *fp) {
|
if (cf->field == *fp) {
|
||||||
ulint col_n = is_virtual
|
|
||||||
? dict_create_v_col_pos(
|
|
||||||
num_v, i)
|
|
||||||
: i - num_v;
|
|
||||||
|
|
||||||
if (innobase_rename_column_try(
|
if (innobase_rename_column_try(
|
||||||
ctx->old_table, trx, table_name,
|
ctx->old_table, trx, table_name,
|
||||||
col_n,
|
|
||||||
cf->field->field_name.str,
|
cf->field->field_name.str,
|
||||||
cf->field_name.str,
|
cf->field_name.str, true)) {
|
||||||
ctx->need_rebuild())) {
|
|
||||||
return(true);
|
return(true);
|
||||||
}
|
}
|
||||||
goto processed_field;
|
goto processed_field;
|
||||||
|
|
@ -9010,35 +8984,62 @@ processed_field:
|
||||||
return(false);
|
return(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Convert field type and length to InnoDB format */
|
||||||
|
static void get_type(const Field& f, ulint& prtype, ulint& mtype, ulint& len)
|
||||||
|
{
|
||||||
|
mtype = get_innobase_type_from_mysql_type(&prtype, &f);
|
||||||
|
len = f.pack_length();
|
||||||
|
prtype |= f.type();
|
||||||
|
if (f.type() == MYSQL_TYPE_VARCHAR) {
|
||||||
|
auto l = static_cast<const Field_varstring&>(f).length_bytes;
|
||||||
|
len -= l;
|
||||||
|
if (l == 2) prtype |= DATA_LONG_TRUE_VARCHAR;
|
||||||
|
}
|
||||||
|
if (!f.real_maybe_null()) prtype |= DATA_NOT_NULL;
|
||||||
|
if (f.binary()) prtype |= DATA_BINARY_TYPE;
|
||||||
|
if (f.table->versioned()) {
|
||||||
|
if (&f == f.table->field[f.table->s->row_start_field]) {
|
||||||
|
prtype |= DATA_VERS_START;
|
||||||
|
} else if (&f == f.table->field[f.table->s->row_end_field]) {
|
||||||
|
prtype |= DATA_VERS_END;
|
||||||
|
} else if (!(f.flags & VERS_UPDATE_UNVERSIONED_FLAG)) {
|
||||||
|
prtype |= DATA_VERSIONED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!f.stored_in_db()) prtype |= DATA_VIRTUAL;
|
||||||
|
|
||||||
|
if (dtype_is_string_type(mtype)) {
|
||||||
|
prtype |= ulint(f.charset()->number) << 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Enlarge a column in the data dictionary tables.
|
/** Enlarge a column in the data dictionary tables.
|
||||||
@param user_table InnoDB table that was being altered
|
@param user_table InnoDB table that was being altered
|
||||||
@param trx data dictionary transaction
|
@param trx data dictionary transaction
|
||||||
@param table_name Table name in MySQL
|
@param table_name Table name in MySQL
|
||||||
@param nth_col 0-based index of the column
|
@param pos 0-based index to user_table->cols[] or user_table->v_cols[]
|
||||||
@param new_len new column length, in bytes
|
@param f new column
|
||||||
|
@param cf column modification
|
||||||
@param is_v if it's a virtual column
|
@param is_v if it's a virtual column
|
||||||
@retval true Failure
|
@retval true Failure
|
||||||
@retval false Success */
|
@retval false Success */
|
||||||
static MY_ATTRIBUTE((nonnull, warn_unused_result))
|
static MY_ATTRIBUTE((nonnull, warn_unused_result))
|
||||||
bool
|
bool
|
||||||
innobase_enlarge_column_try(
|
innobase_rename_or_enlarge_column_try(
|
||||||
/*========================*/
|
|
||||||
const dict_table_t* user_table,
|
const dict_table_t* user_table,
|
||||||
trx_t* trx,
|
trx_t* trx,
|
||||||
const char* table_name,
|
const char* table_name,
|
||||||
ulint nth_col,
|
ulint pos,
|
||||||
ulint new_len,
|
const Field& f,
|
||||||
|
const Create_field& cf,
|
||||||
bool is_v)
|
bool is_v)
|
||||||
{
|
{
|
||||||
pars_info_t* info;
|
|
||||||
dberr_t error;
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
dict_col_t* col;
|
dict_col_t* col;
|
||||||
#endif /* UNIV_DEBUG */
|
#endif /* UNIV_DEBUG */
|
||||||
dict_v_col_t* v_col;
|
dict_v_col_t* v_col;
|
||||||
ulint pos;
|
|
||||||
|
|
||||||
DBUG_ENTER("innobase_enlarge_column_try");
|
DBUG_ENTER("innobase_rename_or_enlarge_column_try");
|
||||||
|
|
||||||
DBUG_ASSERT(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX);
|
DBUG_ASSERT(trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX);
|
||||||
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
|
ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH);
|
||||||
|
|
@ -9046,21 +9047,25 @@ innobase_enlarge_column_try(
|
||||||
ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
|
ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
|
||||||
|
|
||||||
if (is_v) {
|
if (is_v) {
|
||||||
v_col = dict_table_get_nth_v_col(user_table, nth_col);
|
v_col = dict_table_get_nth_v_col(user_table, pos);
|
||||||
pos = dict_create_v_col_pos(v_col->v_pos, v_col->m_col.ind);
|
pos = dict_create_v_col_pos(v_col->v_pos, v_col->m_col.ind);
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
col = &v_col->m_col;
|
col = &v_col->m_col;
|
||||||
#endif /* UNIV_DEBUG */
|
#endif /* UNIV_DEBUG */
|
||||||
} else {
|
} else {
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
col = dict_table_get_nth_col(user_table, nth_col);
|
col = dict_table_get_nth_col(user_table, pos);
|
||||||
#endif /* UNIV_DEBUG */
|
#endif /* UNIV_DEBUG */
|
||||||
pos = nth_col;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ulint prtype, mtype, len;
|
||||||
|
get_type(f, prtype, mtype, len);
|
||||||
|
DBUG_ASSERT(!dtype_is_string_type(col->mtype)
|
||||||
|
|| col->mbminlen == cf.charset->mbminlen);
|
||||||
|
DBUG_ASSERT(col->len <= len);
|
||||||
|
|
||||||
#ifdef UNIV_DEBUG
|
#ifdef UNIV_DEBUG
|
||||||
ut_ad(col->len < new_len);
|
switch (mtype) {
|
||||||
switch (col->mtype) {
|
|
||||||
case DATA_FIXBINARY:
|
case DATA_FIXBINARY:
|
||||||
case DATA_CHAR:
|
case DATA_CHAR:
|
||||||
case DATA_MYSQL:
|
case DATA_MYSQL:
|
||||||
|
|
@ -9068,120 +9073,124 @@ innobase_enlarge_column_try(
|
||||||
and ROW_FORMAT is not REDUNDANT and mbminlen<mbmaxlen.
|
and ROW_FORMAT is not REDUNDANT and mbminlen<mbmaxlen.
|
||||||
That is, we treat a UTF-8 CHAR(n) column somewhat like
|
That is, we treat a UTF-8 CHAR(n) column somewhat like
|
||||||
a VARCHAR. */
|
a VARCHAR. */
|
||||||
if (user_table->not_redundant()) {
|
ut_ad(!user_table->not_redundant() || col->len == len);
|
||||||
ut_error;
|
break;
|
||||||
}
|
|
||||||
case DATA_BINARY:
|
case DATA_BINARY:
|
||||||
case DATA_VARCHAR:
|
case DATA_VARCHAR:
|
||||||
case DATA_VARMYSQL:
|
case DATA_VARMYSQL:
|
||||||
case DATA_DECIMAL:
|
case DATA_DECIMAL:
|
||||||
case DATA_BLOB:
|
case DATA_BLOB:
|
||||||
break;
|
break;
|
||||||
|
case DATA_INT:
|
||||||
|
if (!user_table->not_redundant()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
ut_error;
|
ut_ad(col->prtype == prtype);
|
||||||
|
ut_ad(col->mtype == mtype);
|
||||||
|
ut_ad(col->len == len);
|
||||||
}
|
}
|
||||||
#endif /* UNIV_DEBUG */
|
#endif /* UNIV_DEBUG */
|
||||||
info = pars_info_create();
|
|
||||||
|
|
||||||
pars_info_add_ull_literal(info, "tableid", user_table->id);
|
const char* col_name = col->name(*user_table);
|
||||||
pars_info_add_int4_literal(info, "nth", pos);
|
const bool same_name = !strcmp(col_name, f.field_name.str);
|
||||||
pars_info_add_int4_literal(info, "new", new_len);
|
|
||||||
|
|
||||||
trx->op_info = "resizing column in SYS_COLUMNS";
|
if (!same_name
|
||||||
|
&& innobase_rename_column_try(user_table, trx, table_name,
|
||||||
error = que_eval_sql(
|
col_name, f.field_name.str,
|
||||||
info,
|
false)) {
|
||||||
"PROCEDURE RESIZE_SYS_COLUMNS_PROC () IS\n"
|
|
||||||
"BEGIN\n"
|
|
||||||
"UPDATE SYS_COLUMNS SET LEN=:new\n"
|
|
||||||
"WHERE TABLE_ID=:tableid AND POS=:nth;\n"
|
|
||||||
"END;\n",
|
|
||||||
FALSE, trx);
|
|
||||||
|
|
||||||
DBUG_EXECUTE_IF("ib_resize_column_error",
|
|
||||||
error = DB_OUT_OF_FILE_SPACE;);
|
|
||||||
|
|
||||||
trx->op_info = "";
|
|
||||||
trx->error_state = DB_SUCCESS;
|
|
||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
|
||||||
my_error_innodb(error, table_name, 0);
|
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(false);
|
if (same_name
|
||||||
|
&& col->prtype == prtype && col->mtype == mtype
|
||||||
|
&& col->len == len) {
|
||||||
|
DBUG_RETURN(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
DBUG_RETURN(innodb_insert_sys_columns(user_table->id, pos,
|
||||||
|
f.field_name.str,
|
||||||
|
mtype, prtype, len,
|
||||||
|
is_v ? v_col->num_base : 0,
|
||||||
|
trx, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Enlarge columns in the data dictionary tables.
|
/** Rename or enlarge columns in the data dictionary cache
|
||||||
|
as part of commit_try_norebuild().
|
||||||
@param ha_alter_info Data used during in-place alter.
|
@param ha_alter_info Data used during in-place alter.
|
||||||
@param table the TABLE
|
@param ctx In-place ALTER TABLE context
|
||||||
@param user_table InnoDB table that was being altered
|
@param altered_table metadata after ALTER TABLE
|
||||||
|
@param table metadata before ALTER TABLE
|
||||||
@param trx data dictionary transaction
|
@param trx data dictionary transaction
|
||||||
@param table_name Table name in MySQL
|
@param table_name Table name in MySQL
|
||||||
@retval true Failure
|
@retval true Failure
|
||||||
@retval false Success */
|
@retval false Success */
|
||||||
static MY_ATTRIBUTE((nonnull, warn_unused_result))
|
static MY_ATTRIBUTE((nonnull, warn_unused_result))
|
||||||
bool
|
bool
|
||||||
innobase_enlarge_columns_try(
|
innobase_rename_or_enlarge_columns_try(
|
||||||
/*=========================*/
|
|
||||||
Alter_inplace_info* ha_alter_info,
|
Alter_inplace_info* ha_alter_info,
|
||||||
|
ha_innobase_inplace_ctx*ctx,
|
||||||
|
const TABLE* altered_table,
|
||||||
const TABLE* table,
|
const TABLE* table,
|
||||||
const dict_table_t* user_table,
|
|
||||||
trx_t* trx,
|
trx_t* trx,
|
||||||
const char* table_name)
|
const char* table_name)
|
||||||
{
|
{
|
||||||
|
DBUG_ENTER("innobase_rename_or_enlarge_columns_try");
|
||||||
|
DBUG_ASSERT(ctx);
|
||||||
|
|
||||||
|
if (!(ha_alter_info->handler_flags
|
||||||
|
& (ALTER_COLUMN_EQUAL_PACK_LENGTH
|
||||||
|
| ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
|
||||||
|
| ALTER_COLUMN_NAME))) {
|
||||||
|
DBUG_RETURN(false);
|
||||||
|
}
|
||||||
|
|
||||||
List_iterator_fast<Create_field> cf_it(
|
List_iterator_fast<Create_field> cf_it(
|
||||||
ha_alter_info->alter_info->create_list);
|
ha_alter_info->alter_info->create_list);
|
||||||
ulint i = 0;
|
ulint i = 0;
|
||||||
ulint num_v = 0;
|
ulint num_v = 0;
|
||||||
bool is_v;
|
|
||||||
|
|
||||||
for (Field** fp = table->field; *fp; fp++, i++) {
|
for (Field** fp = table->field; *fp; fp++, i++) {
|
||||||
ulint idx;
|
const bool is_v = !(*fp)->stored_in_db();
|
||||||
|
ulint idx = is_v ? num_v++ : i - num_v;
|
||||||
if (innobase_is_v_fld(*fp)) {
|
|
||||||
is_v = true;
|
|
||||||
idx = num_v;
|
|
||||||
num_v++;
|
|
||||||
} else {
|
|
||||||
idx = i - num_v;
|
|
||||||
is_v = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
cf_it.rewind();
|
cf_it.rewind();
|
||||||
|
Field** af = altered_table->field;
|
||||||
while (Create_field* cf = cf_it++) {
|
while (Create_field* cf = cf_it++) {
|
||||||
if (cf->field == *fp) {
|
if (cf->field == *fp) {
|
||||||
if ((*fp)->is_equal(cf)
|
if (innobase_rename_or_enlarge_column_try(
|
||||||
== IS_EQUAL_PACK_LENGTH
|
ctx->old_table, trx, table_name,
|
||||||
&& innobase_enlarge_column_try(
|
idx, **af, *cf, is_v)) {
|
||||||
user_table, trx, table_name,
|
DBUG_RETURN(true);
|
||||||
idx, static_cast<ulint>(cf->length), is_v)) {
|
|
||||||
return(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
af++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(false);
|
DBUG_RETURN(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Rename or enlarge columns in the data dictionary cache
|
/** Rename or enlarge columns in the data dictionary cache
|
||||||
as part of commit_cache_norebuild().
|
as part of commit_cache_norebuild().
|
||||||
@param ha_alter_info Data used during in-place alter.
|
@param ha_alter_info Data used during in-place alter.
|
||||||
@param table the TABLE
|
@param altered_table metadata after ALTER TABLE
|
||||||
|
@param table metadata before ALTER TABLE
|
||||||
@param user_table InnoDB table that was being altered */
|
@param user_table InnoDB table that was being altered */
|
||||||
static MY_ATTRIBUTE((nonnull))
|
static MY_ATTRIBUTE((nonnull))
|
||||||
void
|
void
|
||||||
innobase_rename_or_enlarge_columns_cache(
|
innobase_rename_or_enlarge_columns_cache(
|
||||||
/*=====================================*/
|
/*=====================================*/
|
||||||
Alter_inplace_info* ha_alter_info,
|
Alter_inplace_info* ha_alter_info,
|
||||||
|
const TABLE* altered_table,
|
||||||
const TABLE* table,
|
const TABLE* table,
|
||||||
dict_table_t* user_table)
|
dict_table_t* user_table)
|
||||||
{
|
{
|
||||||
if (!(ha_alter_info->handler_flags
|
if (!(ha_alter_info->handler_flags
|
||||||
& (ALTER_COLUMN_EQUAL_PACK_LENGTH
|
& (ALTER_COLUMN_EQUAL_PACK_LENGTH
|
||||||
|
| ALTER_COLUMN_EQUAL_PACK_LENGTH_EXT
|
||||||
| ALTER_COLUMN_NAME))) {
|
| ALTER_COLUMN_NAME))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -9195,26 +9204,33 @@ innobase_rename_or_enlarge_columns_cache(
|
||||||
bool is_virtual = innobase_is_v_fld(*fp);
|
bool is_virtual = innobase_is_v_fld(*fp);
|
||||||
|
|
||||||
cf_it.rewind();
|
cf_it.rewind();
|
||||||
|
Field** af = altered_table->field;
|
||||||
while (Create_field* cf = cf_it++) {
|
while (Create_field* cf = cf_it++) {
|
||||||
if (cf->field != *fp) {
|
if (cf->field != *fp) {
|
||||||
|
af++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulint col_n = is_virtual ? num_v : i - num_v;
|
ulint col_n = is_virtual ? num_v : i - num_v;
|
||||||
|
dict_col_t *col = is_virtual
|
||||||
|
? &dict_table_get_nth_v_col(user_table, col_n)
|
||||||
|
->m_col
|
||||||
|
: dict_table_get_nth_col(user_table, col_n);
|
||||||
|
const bool is_string= dtype_is_string_type(col->mtype);
|
||||||
|
DBUG_ASSERT(!is_string
|
||||||
|
|| (*af)->charset() == cf->charset);
|
||||||
|
DBUG_ASSERT(col->mbminlen
|
||||||
|
== (is_string
|
||||||
|
? (*af)->charset()->mbminlen : 0));
|
||||||
|
ulint prtype, mtype, len;
|
||||||
|
get_type(**af, prtype, mtype, len);
|
||||||
|
DBUG_ASSERT(is_string == dtype_is_string_type(mtype));
|
||||||
|
|
||||||
if ((*fp)->is_equal(cf) == IS_EQUAL_PACK_LENGTH) {
|
col->prtype = prtype;
|
||||||
dict_col_t *col = is_virtual ?
|
col->mtype = mtype;
|
||||||
&dict_table_get_nth_v_col(
|
col->len = len;
|
||||||
user_table, col_n)->m_col
|
col->mbmaxlen = is_string
|
||||||
: dict_table_get_nth_col(
|
? (*af)->charset()->mbmaxlen : 0;
|
||||||
user_table, col_n);
|
|
||||||
col->len = cf->length;
|
|
||||||
if (col->len > 255
|
|
||||||
&& (col->prtype & DATA_MYSQL_TRUE_VARCHAR)
|
|
||||||
== DATA_MYSQL_TRUE_VARCHAR) {
|
|
||||||
col->prtype |= DATA_LONG_TRUE_VARCHAR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((*fp)->flags & FIELD_IS_RENAMED) {
|
if ((*fp)->flags & FIELD_IS_RENAMED) {
|
||||||
dict_mem_table_col_rename(
|
dict_mem_table_col_rename(
|
||||||
|
|
@ -10126,17 +10142,9 @@ commit_try_norebuild(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ha_alter_info->handler_flags
|
if (innobase_rename_or_enlarge_columns_try(ha_alter_info, ctx,
|
||||||
& ALTER_COLUMN_NAME)
|
altered_table, old_table,
|
||||||
&& innobase_rename_columns_try(ha_alter_info, ctx, old_table,
|
trx, table_name)) {
|
||||||
trx, table_name)) {
|
|
||||||
DBUG_RETURN(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ha_alter_info->handler_flags
|
|
||||||
& ALTER_COLUMN_EQUAL_PACK_LENGTH)
|
|
||||||
&& innobase_enlarge_columns_try(ha_alter_info, old_table,
|
|
||||||
ctx->old_table, trx, table_name)) {
|
|
||||||
DBUG_RETURN(true);
|
DBUG_RETURN(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -10148,7 +10156,13 @@ commit_try_norebuild(
|
||||||
}
|
}
|
||||||
#endif /* MYSQL_RENAME_INDEX */
|
#endif /* MYSQL_RENAME_INDEX */
|
||||||
|
|
||||||
if (!ctx->is_instant() && ha_alter_info->handler_flags
|
if (ctx->is_instant()) {
|
||||||
|
DBUG_RETURN(innobase_instant_try(ha_alter_info, ctx,
|
||||||
|
altered_table, old_table,
|
||||||
|
trx));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ha_alter_info->handler_flags
|
||||||
& (ALTER_DROP_VIRTUAL_COLUMN | ALTER_ADD_VIRTUAL_COLUMN)) {
|
& (ALTER_DROP_VIRTUAL_COLUMN | ALTER_ADD_VIRTUAL_COLUMN)) {
|
||||||
if ((ha_alter_info->handler_flags & ALTER_DROP_VIRTUAL_COLUMN)
|
if ((ha_alter_info->handler_flags & ALTER_DROP_VIRTUAL_COLUMN)
|
||||||
&& innobase_drop_virtual_try(ha_alter_info, ctx->old_table,
|
&& innobase_drop_virtual_try(ha_alter_info, ctx->old_table,
|
||||||
|
|
@ -10176,14 +10190,14 @@ commit_try_norebuild(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(innobase_instant_try(ha_alter_info, ctx, altered_table,
|
DBUG_RETURN(false);
|
||||||
old_table, trx));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Commit the changes to the data dictionary cache
|
/** Commit the changes to the data dictionary cache
|
||||||
after a successful commit_try_norebuild() call.
|
after a successful commit_try_norebuild() call.
|
||||||
@param ha_alter_info algorithm=inplace context
|
@param ha_alter_info algorithm=inplace context
|
||||||
@param ctx In-place ALTER TABLE context for the current partition
|
@param ctx In-place ALTER TABLE context for the current partition
|
||||||
|
@param altered_table the TABLE after the ALTER
|
||||||
@param table the TABLE before the ALTER
|
@param table the TABLE before the ALTER
|
||||||
@param trx Data dictionary transaction
|
@param trx Data dictionary transaction
|
||||||
(will be started and committed, for DROP INDEX) */
|
(will be started and committed, for DROP INDEX) */
|
||||||
|
|
@ -10193,6 +10207,7 @@ commit_cache_norebuild(
|
||||||
/*===================*/
|
/*===================*/
|
||||||
Alter_inplace_info* ha_alter_info,
|
Alter_inplace_info* ha_alter_info,
|
||||||
ha_innobase_inplace_ctx*ctx,
|
ha_innobase_inplace_ctx*ctx,
|
||||||
|
const TABLE* altered_table,
|
||||||
const TABLE* table,
|
const TABLE* table,
|
||||||
trx_t* trx)
|
trx_t* trx)
|
||||||
{
|
{
|
||||||
|
|
@ -10337,7 +10352,7 @@ commit_cache_norebuild(
|
||||||
|
|
||||||
if (!ctx->is_instant()) {
|
if (!ctx->is_instant()) {
|
||||||
innobase_rename_or_enlarge_columns_cache(
|
innobase_rename_or_enlarge_columns_cache(
|
||||||
ha_alter_info, table, ctx->new_table);
|
ha_alter_info, altered_table, table, ctx->new_table);
|
||||||
} else {
|
} else {
|
||||||
ut_ad(ctx->col_map);
|
ut_ad(ctx->col_map);
|
||||||
|
|
||||||
|
|
@ -11019,6 +11034,7 @@ foreign_fail:
|
||||||
" key constraints.");
|
" key constraints.");
|
||||||
} else {
|
} else {
|
||||||
commit_cache_norebuild(ha_alter_info, ctx,
|
commit_cache_norebuild(ha_alter_info, ctx,
|
||||||
|
altered_table,
|
||||||
table, trx);
|
table, trx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue