From d95b195a2074b2aa685b0fc15917f683ab53f743 Mon Sep 17 00:00:00 2001
From: Sergey Vojtovich <svoj@mariadb.org>
Date: Mon, 26 Aug 2024 12:56:43 +0400
Subject: [PATCH] ALTER TABLE fixes for high-level indexes

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         | 109 +++++++++++++--
 sql/handler.cc                      |   1 +
 sql/sql_table.cc                    |  49 +++++--
 5 files changed, 523 insertions(+), 28 deletions(-)

diff --git a/mysql-test/main/vector,myisam.rdiff b/mysql-test/main/vector,myisam.rdiff
index 383617397dd..a4447d27c4d 100644
--- a/mysql-test/main/vector,myisam.rdiff
+++ b/mysql-test/main/vector,myisam.rdiff
@@ -160,14 +160,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
@@ -249,14 +248,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
@@ -282,10 +281,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 0a09632b088..f40ee3b3ff5 100644
--- a/mysql-test/main/vector.result
+++ b/mysql-test/main/vector.result
@@ -546,7 +546,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
@@ -613,7 +613,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
@@ -637,4 +637,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 35de32728a4..6bb488afeaa 100644
--- a/mysql-test/main/vector.test
+++ b/mysql-test/main/vector.test
@@ -246,12 +246,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;
 
@@ -273,17 +268,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;
+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 drop index v, algorithm=copy;
+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;
-create vector index v on t1(v) algorithm=copy;
+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 18268378f42..b780b6d2017 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -5737,6 +5737,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 870c8cb965a..c487b01de9b 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -6201,7 +6201,7 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info,
         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))
             {
@@ -6272,7 +6272,7 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info,
       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))
         {
@@ -6298,7 +6298,7 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info,
       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()))
         {
@@ -6355,7 +6355,7 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info,
       }
       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))
           {
@@ -6767,7 +6767,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<KEY*>(table->s->keys)) ||
+  if (! (ha_alter_info->index_drop_buffer=
+           thd->alloc<KEY*>(table->s->total_keys)) ||
       ! (ha_alter_info->index_add_buffer=
            thd->alloc<uint>(alter_info->key_list.elements)) ||
       ha_alter_info->rename_keys.reserve(ha_alter_info->index_add_count) ||
@@ -6891,7 +6892,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;
@@ -7068,7 +7069,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;
@@ -7083,8 +7084,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.
@@ -7185,6 +7187,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;
@@ -7266,8 +7271,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->keys < table->s->total_keys &&
+      (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);
 }
@@ -8381,7 +8398,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
   if ((create_info->fields_option_struct= 
          thd->calloc<ha_field_option_struct*>(table->s->fields)) == NULL ||
       (create_info->indexes_option_struct= 
-         thd->calloc<ha_index_option_struct*>(table->s->keys)) == NULL)
+         thd->calloc<ha_index_option_struct*>(table->s->total_keys)) == NULL)
     DBUG_RETURN(1);
 
   if (merge_engine_options(table->s->option_list, create_info->option_list,
@@ -11224,6 +11241,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=
@@ -11369,6 +11397,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. */
-- 
2.30.9