From 7aa6bb3aa3162e71796c135f8aa820419a8b468e Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Mon, 26 Aug 2024 12:56:43 +0400 Subject: [PATCH] ALTER TABLE fixes for high-level indexes (ii) Disable non-copy ALTER algorithms when VECTOR index is affected. Engines are not supposed to handle high-level indexes anyway. Also fixed misbehaving IF [NOT] EXISTS variants. --- mysql-test/main/vector,myisam.rdiff | 203 +++++++++++++++++++++++++++- mysql-test/main/vector.result | 189 +++++++++++++++++++++++++- mysql-test/main/vector.test | 113 ++++++++++++++-- sql/handler.cc | 1 + sql/sql_table.cc | 49 +++++-- 5 files changed, 525 insertions(+), 30 deletions(-) diff --git a/mysql-test/main/vector,myisam.rdiff b/mysql-test/main/vector,myisam.rdiff index 619acdb1d95..e11c4b58f2a 100644 --- a/mysql-test/main/vector,myisam.rdiff +++ b/mysql-test/main/vector,myisam.rdiff @@ -161,14 +161,13 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( -@@ -460,12 +464,14 @@ +@@ -464,12 +464,14 @@ PRIMARY KEY (`id`), KEY `a` (`id`), VECTOR KEY `v` (`v`) -) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci --alter table t1 drop index a, algorithm=copy; +) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci -+drop index a on t1; + drop index a on t1; db.opt -t1#i#01.ibd +t1#i#01.MYD @@ -250,14 +249,14 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( -@@ -534,24 +539,27 @@ +@@ -539,24 +539,27 @@ `v` blob NOT NULL, PRIMARY KEY (`id`), VECTOR KEY `v` (`v`) -) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci # CREATE/DROP INDEX, ALGORITHM=COPY (vector) - alter table t1 drop index v, algorithm=copy; + drop index v on t1; db.opt +t1.MYD +t1.MYI @@ -283,10 +282,202 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( -@@ -565,5 +567,5 @@ +@@ -567,7 +567,7 @@ `v` blob NOT NULL, PRIMARY KEY (`id`), VECTOR KEY `v` (`v`) -) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci ++) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + # ADD/DROP INDEX, ALGORITHM=INPLACE (non-vector) + alter table t1 add index a(id), algorithm=inplace; + ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +@@ -590,31 +590,15 @@ + alter table t1 modify column v mediumblob not null, algorithm=inplace; + ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY + # ADD/CHANGE/DROP/MODIFY COLUMN, ALGORITHM=INPLACE (non-vector) +-alter table t1 add column a varchar(10), algorithm=inplace; +-alter table t1 change column a a varchar(20), algorithm=inplace; +-alter table t1 modify column a varchar(30), algorithm=inplace; +-alter table t1 drop column a, algorithm=inplace; +-db.opt +-t1#i#01.ibd +-t1.frm +-t1.ibd +-show create table t1; +-Table Create Table +-t1 CREATE TABLE `t1` ( +- `id` int(11) NOT NULL AUTO_INCREMENT, +- `v` blob NOT NULL, +- PRIMARY KEY (`id`), +- VECTOR KEY `v` (`v`) +-) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + # ENABLE/DISABLE INDEXES + alter table t1 disable keys; + alter table t1 enable keys; +-Warnings: +-Note 1031 Storage engine InnoDB of the table `test`.`t1` doesn't have this option + db.opt +-t1#i#01.ibd ++t1#i#01.MYD ++t1#i#01.MYI ++t1.MYD ++t1.MYI + t1.frm +-t1.ibd + show create table t1; + Table Create Table + t1 CREATE TABLE `t1` ( +@@ -606,13 +606,15 @@ + `v` blob NOT NULL, + PRIMARY KEY (`id`), + VECTOR KEY `v` (`v`) +-) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci ++) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + # RENAME COLUMN (vector) + alter table t1 rename column v to w; + db.opt +-t1#i#01.ibd ++t1#i#01.MYD ++t1#i#01.MYI ++t1.MYD ++t1.MYI + t1.frm +-t1.ibd + show create table t1; + Table Create Table + t1 CREATE TABLE `t1` ( +@@ -622,14 +622,16 @@ + `w` blob NOT NULL, + PRIMARY KEY (`id`), + VECTOR KEY `v` (`w`) +-) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci ++) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + alter table t1 rename column w to v; + # RENAME INDEX (vector) + alter table t1 rename key v to w; + db.opt +-t1#i#01.ibd ++t1#i#01.MYD ++t1#i#01.MYI ++t1.MYD ++t1.MYI + t1.frm +-t1.ibd + show create table t1; + Table Create Table + t1 CREATE TABLE `t1` ( +@@ -639,7 +639,7 @@ + `v` blob NOT NULL, + PRIMARY KEY (`id`), + VECTOR KEY `w` (`v`) +-) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci ++) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + alter table t1 rename key w to v; + # IF [NOT] EXISTS + create vector index if not exists v on t1(v); +@@ -650,15 +650,16 @@ + Warnings: + Note 1091 Can't DROP INDEX `v`; check that it exists + db.opt ++t1.MYD ++t1.MYI + t1.frm +-t1.ibd + show create table t1; + Table Create Table + t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `v` blob NOT NULL, + PRIMARY KEY (`id`) +-) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci ++) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + create vector index if not exists v on t1(v); + # CHANGE/MODIFY/DROP COLUMN (vector) + alter table t1 modify column v int; +@@ -666,34 +666,6 @@ + alter table t1 alter key if exists v ignored; + alter table t1 alter key if exists v not ignored; + # ENGINE +-alter table t1 engine=myisam; +-db.opt +-t1#i#01.MYD +-t1#i#01.MYI +-t1.MYD +-t1.MYI +-t1.frm +-show create table t1; +-Table Create Table +-t1 CREATE TABLE `t1` ( +- `id` int(11) NOT NULL AUTO_INCREMENT, +- `v` blob NOT NULL, +- PRIMARY KEY (`id`), +- VECTOR KEY `v` (`v`) +-) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +-alter table t1 engine=innodb; +-db.opt +-t1#i#01.ibd +-t1.frm +-t1.ibd +-show create table t1; +-Table Create Table +-t1 CREATE TABLE `t1` ( +- `id` int(11) NOT NULL AUTO_INCREMENT, +- `v` blob NOT NULL, +- PRIMARY KEY (`id`), +- VECTOR KEY `v` (`v`) +-) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + # CHANGE/MODIFY/DROP COLUMN (vector) + alter table t1 modify column v int; + ERROR HY000: Incorrect arguments to VECTOR INDEX +@@ -671,9 +672,11 @@ + ERROR 42000: All parts of a VECTOR index must be NOT NULL + alter table t1 modify column v tinyblob not null; + db.opt +-t1#i#01.ibd ++t1#i#01.MYD ++t1#i#01.MYI ++t1.MYD ++t1.MYI + t1.frm +-t1.ibd + show create table t1; + Table Create Table + t1 CREATE TABLE `t1` ( +@@ -681,12 +684,14 @@ + `v` tinyblob NOT NULL, + PRIMARY KEY (`id`), + VECTOR KEY `v` (`v`) +-) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci ++) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + alter table t1 change column v v blob not null; + db.opt +-t1#i#01.ibd ++t1#i#01.MYD ++t1#i#01.MYI ++t1.MYD ++t1.MYI + t1.frm +-t1.ibd + show create table t1; + Table Create Table + t1 CREATE TABLE `t1` ( +@@ -699,15 +699,16 @@ + `v` blob NOT NULL, + PRIMARY KEY (`id`), + VECTOR KEY `v` (`v`) +-) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci ++) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci + alter table t1 drop column v; + db.opt ++t1.MYD ++t1.MYI + t1.frm +-t1.ibd + show create table t1; + Table Create Table + t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`id`) +-) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci drop table t1; diff --git a/mysql-test/main/vector.result b/mysql-test/main/vector.result index 1d55f45e7ea..6349aefbd12 100644 --- a/mysql-test/main/vector.result +++ b/mysql-test/main/vector.result @@ -553,7 +553,7 @@ t1 CREATE TABLE `t1` ( KEY `a` (`id`), VECTOR KEY `v` (`v`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci -alter table t1 drop index a, algorithm=copy; +drop index a on t1; db.opt t1#i#01.ibd t1.frm @@ -620,7 +620,7 @@ t1 CREATE TABLE `t1` ( VECTOR KEY `v` (`v`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci # CREATE/DROP INDEX, ALGORITHM=COPY (vector) -alter table t1 drop index v, algorithm=copy; +drop index v on t1; db.opt t1.frm t1.ibd @@ -644,4 +644,189 @@ t1 CREATE TABLE `t1` ( PRIMARY KEY (`id`), VECTOR KEY `v` (`v`) ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +# ADD/DROP INDEX, ALGORITHM=INPLACE (non-vector) +alter table t1 add index a(id), algorithm=inplace; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +alter table t1 add index a(id); +alter table t1 drop index a, algorithm=inplace; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +alter table t1 drop index a; +# ADD/DROP INDEX, ALGORITHM=INPLACE (vector) +alter table t1 drop index v, algorithm=inplace; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +alter table t1 drop index v; +alter table t1 add vector index v(v), algorithm=inplace; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +alter table t1 add vector index v(v); +# CHANGE/DROP/MODIFY COLUMN, ALGORITHM=INPLACE (vector) +alter table t1 change column v v mediumblob not null, algorithm=inplace; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +alter table t1 drop column v, algorithm=inplace; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +alter table t1 modify column v mediumblob not null, algorithm=inplace; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +# ADD/CHANGE/DROP/MODIFY COLUMN, ALGORITHM=INPLACE (non-vector) +alter table t1 add column a varchar(10), algorithm=inplace; +alter table t1 change column a a varchar(20), algorithm=inplace; +alter table t1 modify column a varchar(30), algorithm=inplace; +alter table t1 drop column a, algorithm=inplace; +db.opt +t1#i#01.ibd +t1.frm +t1.ibd +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `v` blob NOT NULL, + PRIMARY KEY (`id`), + VECTOR KEY `v` (`v`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +# ENABLE/DISABLE INDEXES +alter table t1 disable keys; +alter table t1 enable keys; +Warnings: +Note 1031 Storage engine InnoDB of the table `test`.`t1` doesn't have this option +db.opt +t1#i#01.ibd +t1.frm +t1.ibd +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `v` blob NOT NULL, + PRIMARY KEY (`id`), + VECTOR KEY `v` (`v`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +# RENAME COLUMN (vector) +alter table t1 rename column v to w; +db.opt +t1#i#01.ibd +t1.frm +t1.ibd +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `w` blob NOT NULL, + PRIMARY KEY (`id`), + VECTOR KEY `v` (`w`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +alter table t1 rename column w to v; +# RENAME INDEX (vector) +alter table t1 rename key v to w; +db.opt +t1#i#01.ibd +t1.frm +t1.ibd +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `v` blob NOT NULL, + PRIMARY KEY (`id`), + VECTOR KEY `w` (`v`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +alter table t1 rename key w to v; +# IF [NOT] EXISTS +create vector index if not exists v on t1(v); +Warnings: +Note 1061 Duplicate key name 'v' +drop index if exists v on t1; +drop index if exists v on t1; +Warnings: +Note 1091 Can't DROP INDEX `v`; check that it exists +db.opt +t1.frm +t1.ibd +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `v` blob NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +create vector index if not exists v on t1(v); +alter table t1 rename key if exists v to w; +alter table t1 rename key if exists w to v; +alter table t1 alter key if exists v ignored; +alter table t1 alter key if exists v not ignored; +# ENGINE +alter table t1 engine=myisam; +db.opt +t1#i#01.MYD +t1#i#01.MYI +t1.MYD +t1.MYI +t1.frm +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `v` blob NOT NULL, + PRIMARY KEY (`id`), + VECTOR KEY `v` (`v`) +) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +alter table t1 engine=innodb; +db.opt +t1#i#01.ibd +t1.frm +t1.ibd +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `v` blob NOT NULL, + PRIMARY KEY (`id`), + VECTOR KEY `v` (`v`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +# CHANGE/MODIFY/DROP COLUMN (vector) +alter table t1 modify column v int; +ERROR HY000: Incorrect arguments to VECTOR INDEX +alter table t1 change column v v int; +ERROR HY000: Incorrect arguments to VECTOR INDEX +alter table t1 modify column v blob; +ERROR 42000: All parts of a VECTOR index must be NOT NULL +alter table t1 change column v v blob; +ERROR 42000: All parts of a VECTOR index must be NOT NULL +alter table t1 modify column v tinyblob not null; +db.opt +t1#i#01.ibd +t1.frm +t1.ibd +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `v` tinyblob NOT NULL, + PRIMARY KEY (`id`), + VECTOR KEY `v` (`v`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +alter table t1 change column v v blob not null; +db.opt +t1#i#01.ibd +t1.frm +t1.ibd +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `v` blob NOT NULL, + PRIMARY KEY (`id`), + VECTOR KEY `v` (`v`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +alter table t1 drop column v; +db.opt +t1.frm +t1.ibd +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +drop table t1; +create table t1(v blob not null, vector index(v)); +alter table t1 add column a int; drop table t1; diff --git a/mysql-test/main/vector.test b/mysql-test/main/vector.test index ff73811d334..8820537a387 100644 --- a/mysql-test/main/vector.test +++ b/mysql-test/main/vector.test @@ -251,12 +251,7 @@ show create table t1; create index a on t1(id) algorithm=copy; list_files $datadir/test; show create table t1; -if ($MTR_COMBINATION_MYISAM) { drop index a on t1; -} -if ($MTR_COMBINATION_INNODB) { -alter table t1 drop index a, algorithm=copy; -} list_files $datadir/test; show create table t1; @@ -278,17 +273,111 @@ list_files $datadir/test; show create table t1; --echo # CREATE/DROP INDEX, ALGORITHM=COPY (vector) -if ($MTR_COMBINATION_MYISAM) { -# To be fixed to: drop index v on t1; -alter table t1 drop index v, algorithm=copy; -} -if ($MTR_COMBINATION_INNODB) { -alter table t1 drop index v, algorithm=copy; -} +drop index v on t1; list_files $datadir/test; show create table t1; create vector index v on t1(v) algorithm=copy; list_files $datadir/test; show create table t1; +--echo # ADD/DROP INDEX, ALGORITHM=INPLACE (non-vector) +--error ER_ALTER_OPERATION_NOT_SUPPORTED +alter table t1 add index a(id), algorithm=inplace; +alter table t1 add index a(id); +--error ER_ALTER_OPERATION_NOT_SUPPORTED +alter table t1 drop index a, algorithm=inplace; +alter table t1 drop index a; + +--echo # ADD/DROP INDEX, ALGORITHM=INPLACE (vector) +--error ER_ALTER_OPERATION_NOT_SUPPORTED +alter table t1 drop index v, algorithm=inplace; +alter table t1 drop index v; +--error ER_ALTER_OPERATION_NOT_SUPPORTED +alter table t1 add vector index v(v), algorithm=inplace; +alter table t1 add vector index v(v); + +--echo # CHANGE/DROP/MODIFY COLUMN, ALGORITHM=INPLACE (vector) +--error ER_ALTER_OPERATION_NOT_SUPPORTED +alter table t1 change column v v mediumblob not null, algorithm=inplace; +--error ER_ALTER_OPERATION_NOT_SUPPORTED +alter table t1 drop column v, algorithm=inplace; +--error ER_ALTER_OPERATION_NOT_SUPPORTED +alter table t1 modify column v mediumblob not null, algorithm=inplace; + +--echo # ADD/CHANGE/DROP/MODIFY COLUMN, ALGORITHM=INPLACE (non-vector) +if ($MTR_COMBINATION_INNODB) { +alter table t1 add column a varchar(10), algorithm=inplace; +alter table t1 change column a a varchar(20), algorithm=inplace; +alter table t1 modify column a varchar(30), algorithm=inplace; +alter table t1 drop column a, algorithm=inplace; +list_files $datadir/test; +show create table t1; +} + +--echo # ENABLE/DISABLE INDEXES +alter table t1 disable keys; +alter table t1 enable keys; +list_files $datadir/test; +show create table t1; + +--echo # RENAME COLUMN (vector) +alter table t1 rename column v to w; +list_files $datadir/test; +show create table t1; +alter table t1 rename column w to v; + +--echo # RENAME INDEX (vector) +alter table t1 rename key v to w; +list_files $datadir/test; +show create table t1; +alter table t1 rename key w to v; + +--echo # IF [NOT] EXISTS +create vector index if not exists v on t1(v); +drop index if exists v on t1; +drop index if exists v on t1; +list_files $datadir/test; +show create table t1; +create vector index if not exists v on t1(v); +alter table t1 rename key if exists v to w; +alter table t1 rename key if exists w to v; +alter table t1 alter key if exists v ignored; +alter table t1 alter key if exists v not ignored; + +--echo # ENGINE +if ($MTR_COMBINATION_INNODB) { +alter table t1 engine=myisam; +list_files $datadir/test; +show create table t1; +alter table t1 engine=innodb; +list_files $datadir/test; +show create table t1; +} + +--echo # CHANGE/MODIFY/DROP COLUMN (vector) +--error ER_WRONG_ARGUMENTS +alter table t1 modify column v int; +--error ER_WRONG_ARGUMENTS +alter table t1 change column v v int; +--error ER_INDEX_CANNOT_HAVE_NULL +alter table t1 modify column v blob; +--error ER_INDEX_CANNOT_HAVE_NULL +alter table t1 change column v v blob; +alter table t1 modify column v tinyblob not null; +list_files $datadir/test; +show create table t1; +alter table t1 change column v v blob not null; +list_files $datadir/test; +show create table t1; +alter table t1 drop column v; +list_files $datadir/test; +show create table t1; + +drop table t1; + +# This is supposed to test crash while filling indexes_option_struct array, +# which doesn't happen because alloc_root(0) returns something. Add a test +# anyway and fix indexes_option_struct array allocation. +create table t1(v blob not null, vector index(v)); +alter table t1 add column a int; drop table t1; diff --git a/sql/handler.cc b/sql/handler.cc index 07f0dc8088d..2c5e3904e9c 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5745,6 +5745,7 @@ Alter_inplace_info::Alter_inplace_info(HA_CREATE_INFO *create_info_arg, rename_keys(current_thd->mem_root), modified_part_info(modified_part_info_arg), ignore(ignore_arg), + inplace_supported(HA_ALTER_ERROR), error_if_not_empty(error_non_empty) {} diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a49ea46e28a..b3a52c2cca7 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6228,7 +6228,7 @@ drop_create_field: uint n_key; if (drop->type != Alter_drop::FOREIGN_KEY) { - for (n_key=0; n_key < table->s->keys; n_key++) + for (n_key=0; n_key < table->s->total_keys; n_key++) { if (table->key_info[n_key].name.streq(drop->name)) { @@ -6299,7 +6299,7 @@ drop_create_field: if (!rename_key->alter_if_exists) continue; bool exists= false; - for (uint n_key= 0; n_key < table->s->keys; n_key++) + for (uint n_key= 0; n_key < table->s->total_keys; n_key++) { if (table->key_info[n_key].name.streq(rename_key->old_name)) { @@ -6325,7 +6325,7 @@ drop_create_field: if (!aii->if_exists()) continue; bool exists= false; - for (uint n_key= 0; n_key < table->s->keys; n_key++) + for (uint n_key= 0; n_key < table->s->total_keys; n_key++) { if (table->key_info[n_key].name.streq(aii->name())) { @@ -6382,7 +6382,7 @@ drop_create_field: } if (key->type != Key::FOREIGN_KEY) { - for (n_key=0; n_key < table->s->keys; n_key++) + for (n_key=0; n_key < table->s->total_keys; n_key++) { if (table->key_info[n_key].name.streq(keyname)) { @@ -6794,7 +6794,8 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, /* Allocate result buffers. */ DBUG_ASSERT(ha_alter_info->rename_keys.mem_root() == thd->mem_root); - if (! (ha_alter_info->index_drop_buffer= thd->alloc(table->s->keys)) || + if (! (ha_alter_info->index_drop_buffer= + thd->alloc(table->s->total_keys)) || ! (ha_alter_info->index_add_buffer= thd->alloc(alter_info->key_list.elements)) || ha_alter_info->rename_keys.reserve(ha_alter_info->index_add_count) || @@ -6918,7 +6919,7 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, DBUG_RETURN(true); KEY *key_info= table->key_info; - for (uint i= 0; i < table->s->keys; i++, key_info++) + for (uint i= 0; i < table->s->total_keys; i++, key_info++) { if (!field->part_of_key.is_set(i)) continue; @@ -7095,7 +7096,7 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, with new table. */ KEY *table_key; - KEY *table_key_end= table->key_info + table->s->keys; + KEY *table_key_end= table->key_info + table->s->total_keys; KEY *new_key; KEY *new_key_end= ha_alter_info->key_info_buffer + ha_alter_info->key_count; @@ -7110,8 +7111,9 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, const KEY *const old_pk= table->s->primary_key == MAX_KEY ? NULL : table->key_info + table->s->primary_key; - DBUG_PRINT("info", ("index count old: %d new: %d", - table->s->keys, ha_alter_info->key_count)); + DBUG_PRINT("info", ("index count old: %d total: %d new: %d", + table->s->keys, table->s->total_keys, + ha_alter_info->key_count)); /* Step through all keys of the old table and search matching new keys. @@ -7212,6 +7214,9 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, ha_alter_info->handler_flags|= ALTER_RENAME_INDEX; ha_alter_info->rename_keys.push_back( Alter_inplace_info::Rename_key_pair(old_key, new_key)); + /* Renaming high-level index is algorithm=copy operation. */ + if (old_key->algorithm == HA_KEY_ALG_VECTOR) + ha_alter_info->inplace_supported= HA_ALTER_INPLACE_NOT_SUPPORTED; --ha_alter_info->index_add_count; --ha_alter_info->index_drop_count; @@ -7293,8 +7298,20 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, } else ha_alter_info->handler_flags|= ALTER_ADD_NON_UNIQUE_NON_PRIM_INDEX; + /* Adding high-level index is algorithm=copy operation. */ + if (new_key->algorithm == HA_KEY_ALG_VECTOR) + ha_alter_info->inplace_supported= HA_ALTER_INPLACE_NOT_SUPPORTED; } + /* + Adding/dropping any indexes in a table that already has high-level indexes + may shift high-level indexes numbers. And thus require high-level indexes + rename, which algorithm=inplace (storage engines) shouldn't do. + */ + if (table->s->hlindexes() && + (ha_alter_info->index_drop_count || ha_alter_info->index_add_count)) + ha_alter_info->inplace_supported= HA_ALTER_INPLACE_NOT_SUPPORTED; + DBUG_PRINT("exit", ("handler_flags: %llu", ha_alter_info->handler_flags)); DBUG_RETURN(false); } @@ -8408,7 +8425,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, if ((create_info->fields_option_struct= thd->calloc(table->s->fields)) == NULL || (create_info->indexes_option_struct= - thd->calloc(table->s->keys)) == NULL) + thd->calloc(table->s->total_keys)) == NULL) DBUG_RETURN(1); if (merge_engine_options(table->s->option_list, create_info->option_list, @@ -11312,6 +11329,17 @@ do_continue:; if (fill_alter_inplace_info(thd, table, &ha_alter_info)) goto err_new_table_cleanup; + if (ha_alter_info.inplace_supported == HA_ALTER_INPLACE_NOT_SUPPORTED) + { + if (alter_info->algorithm_is_nocopy(thd)) + { + my_error(ER_ALTER_OPERATION_NOT_SUPPORTED, MYF(0), + alter_info->algorithm_clause(thd), "ALGORITHM=COPY"); + goto err_new_table_cleanup; + } + goto alter_copy; + } + alter_ctx.tmp_storage_engine_name_partitioned= table->file->partition_engine(); alter_ctx.tmp_storage_engine_name.length= @@ -11457,6 +11485,7 @@ do_continue:; cleanup_table_after_inplace_alter_keep_files(&altered_table); } +alter_copy: /* ALTER TABLE using copy algorithm. */ /* Check if ALTER TABLE is compatible with foreign key definitions. */